From 88020f7cf9d63f0732166cc37a1e30b0872c2d9a Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 26 Sep 2026 22:18:32 +0800 Subject: [PATCH] fix(ajax): retain response status in cached results --- src/core/util/ajax.js | 10 +++++++--- test/unit/ajax.test.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/unit/ajax.test.js diff --git a/src/core/util/ajax.js b/src/core/util/ajax.js index 37afe1401c..0c442d1a07 100644 --- a/src/core/util/ajax.js +++ b/src/core/util/ajax.js @@ -4,7 +4,7 @@ import progressbar from '../render/progressbar.js'; import { noop } from './core.js'; /** @typedef {{updatedAt: string}} CacheOpt */ -/** @typedef {{content: string, opt: CacheOpt}} CacheItem */ +/** @typedef {{content: string, opt: CacheOpt, response: ResponseStatus}} CacheItem */ /** @typedef {{ok: boolean, status: number, statusText: string}} ResponseStatus */ /** @type {Record} */ @@ -30,7 +30,10 @@ export function get(url, hasBar = false, headers = {}) { const cached = cache[url]; if (cached) { - return { then: cb => cb(cached.content, cached.opt), abort: noop }; + return { + then: cb => cb(cached.content, cached.opt, cached.response), + abort: noop, + }; } xhr.open('GET', url); @@ -87,9 +90,10 @@ export function get(url, hasBar = false, headers = {}) { opt: { updatedAt: xhr.getResponseHeader('last-modified') ?? '', }, + response: getResponseStatus(event), }); - success(result.content, result.opt, getResponseStatus(event)); + success(result.content, result.opt, result.response); } }); }, diff --git a/test/unit/ajax.test.js b/test/unit/ajax.test.js new file mode 100644 index 0000000000..42e8280385 --- /dev/null +++ b/test/unit/ajax.test.js @@ -0,0 +1,30 @@ +import _mock from 'xhr-mock'; +import { get } from '../../src/core/util/ajax.js'; + +const mock = _mock.default; + +describe('ajax/get', () => { + beforeEach(() => mock.setup()); + afterEach(() => mock.teardown()); + + test('preserves response status when serving cached content', async () => { + const url = '/cached-response-status.md'; + mock.get(url, { status: 200, body: '# Cached page' }); + + const first = await new Promise(resolve => { + get(url).then((content, opt, response) => { + resolve({ content, opt, response }); + }); + }); + const cached = await new Promise(resolve => { + get(url).then((content, opt, response) => { + resolve({ content, opt, response }); + }); + }); + + expect(first.response).toEqual( + expect.objectContaining({ ok: true, status: 200 }), + ); + expect(cached).toEqual(first); + }); +});