Visitar URL original
fix(http): always decode JSON responses as UTF-8 · angular/angular@09bc900 · GitHub
Skip to content

Commit 09bc900

Browse files
SkyZeroZxamishne
authored andcommitted
fix(http): always decode JSON responses as UTF-8
Keep the charset handling added in #70062 limited to text responses. JSON bytes must stay UTF-8 regardless of the Content-Type charset. Fetch defines Body.json() using "parse JSON from bytes". Infra specifies that step as: "Let string be the result of running UTF-8 decode on bytes." https://fetch.spec.whatwg.org/#dom-body-json https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value
1 parent cf1844b commit 09bc900

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

‎packages/common/http/src/fetch.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ export class FetchBackend implements HttpBackend {
342342
switch (request.responseType) {
343343
case 'json':
344344
// stripping the XSSI when present
345-
const text = getTextDecoder(contentType).decode(binContent).replace(XSSI_PREFIX, '');
345+
const text = new TextDecoder().decode(binContent).replace(XSSI_PREFIX, '');
346346
if (text === '') {
347347
return null;
348348
}

‎packages/common/http/test/fetch_spec.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,16 @@ describe('FetchBackend', () => {
230230
expect(res.body!.data).toBe('some data');
231231
});
232232

233+
it('decodes a json response as UTF-8 regardless of its declared charset', async () => {
234+
const promise = trackEvents(backend.handle(TEST_POST.clone({responseType: 'json'})));
235+
fetchMock.mockFlush(HttpStatusCode.Ok, 'OK', JSON.stringify({data: 'café'}), {
236+
'Content-Type': 'application/json; charset=windows-1251',
237+
});
238+
const events = await promise;
239+
const res = events[1] as HttpResponse<{data: string}>;
240+
expect(res.body!.data).toBe('café');
241+
});
242+
233243
it('handles a blank json response', async () => {
234244
const promise = trackEvents(backend.handle(TEST_POST.clone({responseType: 'json'})));
235245
fetchMock.mockFlush(HttpStatusCode.Ok, 'OK', '');

0 commit comments

Comments
 (0)