Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@ export function rejectNoCorsRequestMiddleware(): Connect.NextHandleFunction {
// we choose to reject the request to be safer in case the request handler has any side-effects.
if (
req.headers['sec-fetch-mode'] === 'no-cors' &&
req.headers['sec-fetch-site'] !== 'same-origin'
req.headers['sec-fetch-site'] !== 'same-origin' &&
// we only need to block classic script requests
req.headers['sec-fetch-dest'] === 'script'
) {
res.statusCode = 403
res.end('Cross-origin requests must be made with CORS mode enabled.')
res.end(
'Cross-origin requests for classic scripts must be made with CORS mode enabled. Make sure to set the "crossorigin" attribute on your <script> tag.',
)
return
}
return next()
Expand Down
35 changes: 33 additions & 2 deletions playground/fs-serve/__tests__/fs-serve.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,43 @@ test.runIf(isServe)(
})
expect(res.statusCode).toBe(403)
const body = Buffer.concat(await ArrayFromAsync(res)).toString()
expect(body).toBe(
'Cross-origin requests must be made with CORS mode enabled.',
expect(body).toContain(
'Cross-origin requests for classic scripts must be made with CORS mode enabled.',
)
},
)

test.runIf(isServe)(
'load image with no-cors mode from a different origin should be allowed',
async () => {
const viteTestUrlUrl = new URL(viteTestUrl)

// NOTE: fetch cannot be used here as `fetch` sets some headers automatically
const res = await new Promise<http.IncomingMessage>((resolve, reject) => {
http
.get(
viteTestUrl + '/src/code.js',
{
headers: {
'Sec-Fetch-Dest': 'image',
'Sec-Fetch-Mode': 'no-cors',
'Sec-Fetch-Site': 'same-site',
Origin: 'http://vite.dev',
Host: viteTestUrlUrl.host,
},
},
(res) => {
resolve(res)
},
)
.on('error', (e) => {
reject(e)
})
})
expect(res.statusCode).not.toBe(403)
},
)

// Note: Array.fromAsync is only supported in Node.js 22+
async function ArrayFromAsync<T>(
asyncIterable: AsyncIterable<T>,
Expand Down