问题从何而来
在 Chrome 浏览器中报错,说 "access to image at ... svg' from origin ... No 'Access-Control-Allow-Origin' header ..."
是有一个网站在某一个地方引用了另一个可控网站的 svg 资源,但是是不同的域,所以报错了。在页面上的体现就是一个图标看不见。所以,需要设置另一个网站的 cors 响应头,如果另一个网站是基于 nextjs 开发的话,那么该如何设置呢?
设置 Nextjs 静态文件跨域 Headers
在 Next.js 中配置静态文件的响应头需要使用一个名为 next.config.js 的配置文件。你可以在该文件中添加一个函数 async headers() 来设置你想要的响应头。
以下是一个例子,展示如何设置 xyz 文件夹中所有文件的 Access-Control-Allow-Origin 字段为 *:
// next.config.js
module.exports = {
async headers() {
return [
{
// 匹配所有的静态文件
source: '/xyz/:path*',
// 设置响应头
headers: [
{
key: 'Access-Control-Allow-Origin',
value: '*',
},
],
},
];
},
};
上述配置代码中,source 指定了需要设置响应头的静态文件的 URL 路径,使用 :path* 匹配了所有的路径。headers 数组中包含一个对象,该对象指定了要设置的响应头。
通过这种方式,你可以在 Next.js 应用中为任意静态文件设置响应头,包括在 xyz 文件夹中的文件。
检查
浏览器访问报错的静态资源文件,看响应头是否包含有 'Access-Control-Allow-Origin', 前后比对一下。
补充方法
也可以直接在请求过程中设置 response, 如下
export function allowCors(req, res, origin) {
// CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*'
// when the request's credentials mode is 'include'.
// The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
if (!origin) {
origin = req.headers.origin || '*';
}
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Request-Method', 'HEAD, GET, POST, PUT, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Origin, Referer, Content-Type');
res.setHeader('Access-Control-Allow-Credentials', 'true');
}