Skip to content

Commit 5d3bb99

Browse files
authored
Add option for setting xhr.withCredentials (#13)
* Add option for setting xhr.withCredentials - Support for withCredentials already existed, there was just no way to set it - Test cases might fail in Chrome 80+ due to httpbin cookie settings, see code comments * Fix type-o in test comments
1 parent 5566337 commit 5d3bb99

3 files changed

Lines changed: 54 additions & 3 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ the request is done, or rejects if it fails.
6969
* **options**:
7070
* priority: Defines the order in which requests get sent. One of the following:
7171
* RequestQueue.LOW
72-
* RequestQueue.MEDIUM (default)
72+
* RequestQueue.MEDIUM (default)
7373
* RequestQueue.HIGH
74-
* RequestQueue.HIGHEST
74+
* RequestQueue.HIGHEST
7575

7676
HIGHEST is special: It actually aborts HIGH, MEDIUM or LOW requests to be tried again,
7777
if there are too many requests in flight)
@@ -86,6 +86,7 @@ the request is done, or rejects if it fails.
8686
* image: Returns an Image
8787
* headers: Object of additional headers to set
8888
* auth: contents of the 'Authorization' header if supplied
89+
* withCredentials: Enable or disable sending credentials with cross-site XHR requests (default false)
8990

9091
#### RequestQueue.get(url, {options})
9192
#### RequestQueue.post(url, {options})

src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface Options {
1414
body?: string;
1515
maxRetries?: number;
1616
auth?: string;
17+
withCredentials?: boolean;
1718
headers?: { [key: string]: any };
1819
onProgress?: (evt: ProgressEvent) => void;
1920
}
@@ -220,6 +221,7 @@ export class Request {
220221
maxRetries: number | null
221222
responseType: string | null
222223
auth: string | null
224+
withCredentials: boolean
223225
body: string | FormData | null
224226
headers: { [key: string]: any }
225227

@@ -251,6 +253,7 @@ export class Request {
251253
this.url = url
252254
this.method = method
253255
this.auth = options.auth || null
256+
this.withCredentials = options.withCredentials || false
254257
this.priority = options.priority || RequestPriority.MEDIUM
255258
this.responseType = options.responseType || null
256259
this.body = options.body || null
@@ -269,7 +272,7 @@ export class Request {
269272
* @returns {Promise<any>}
270273
*/
271274
send(): Promise<any> {
272-
const xhr = this.xhr = openXHR(this.method, this.url, false)
275+
const xhr = this.xhr = openXHR(this.method, this.url, this.withCredentials)
273276

274277
if (this.responseType) {
275278
if (this.responseType === 'arraybuffer' ||

src/tests.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,53 @@ test('authorization header', (t : any) => {
3838
})
3939
})
4040

41+
/**
42+
* Tests request with cross-site credentials enabled,
43+
* cookies should be sent to external domain via request headers
44+
*
45+
* Note: If this test fails in Chrome >= 80, it may be due to httpbin
46+
* not setting the `SameSite=None` or `Secure` flags when creating cookies
47+
*
48+
* See https://www.chromestatus.com/feature/5088147346030592 and
49+
* chrome://flags/#same-site-by-default-cookies
50+
*/
51+
test('xhr with credentials', (t : any) => {
52+
t.plan(2)
53+
const requests = new RequestQueue()
54+
const cookie = 'token=xyz';
55+
requests.get(`${TEST_URL}/cookies/set?${cookie}`).then(() => {
56+
requests.get(`${TEST_URL}/headers`, {
57+
withCredentials: true,
58+
responseType: 'json'
59+
}).then((response) => {
60+
t.assert('Cookie' in response.headers)
61+
t.equal(response.headers.Cookie, cookie);
62+
});
63+
}).catch(() => {
64+
t.fail('Request failed')
65+
})
66+
})
67+
68+
/**
69+
* Tests request with cross-site credentials disabled,
70+
* cookies should not be passed to external origin via request headers
71+
*/
72+
test('xhr without credentials', (t : any) => {
73+
t.plan(1)
74+
const requests = new RequestQueue()
75+
const cookie = 'token=xyz';
76+
requests.get(`${TEST_URL}/cookies/set?${cookie}`).then(() => {
77+
requests.get(`${TEST_URL}/headers`, {
78+
withCredentials: false,
79+
responseType: 'json'
80+
}).then((response) => {
81+
t.assert(!('Cookie' in response.headers));
82+
});
83+
}).catch(() => {
84+
t.fail('Request failed')
85+
})
86+
})
87+
4188
test('arraybuffer responseType', (t : any) => {
4289
t.plan(2)
4390
const requests = new RequestQueue()

0 commit comments

Comments
 (0)