前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >跨域资源共享 CORS 错误解析及解决方法

跨域资源共享 CORS 错误解析及解决方法

原创
作者头像
DamonLiu
发布2022-05-08 21:45:31
10.9K0
发布2022-05-08 21:45:31
举报
文章被收录于专栏:知识技能知识技能

我们通常会利用CORS机制实现跨域接口服务的访问,为了简便开发环境、测试环境等不同环境的配置,通常大家会用*通配符标识允许任意域名的请求。但是在需要发送Cookie等身份凭证的情况,用*通配符会出现一些错误

首先理解CORS区分简单请求和预检请求两种常见,预见请求首先使用 OPTIONS 方法发起一个预检请求到服务器

用来获知服务器是否允许该实际请求

当我们设置xhr请求 withCredentials: true ,或者fetch请求 credentials: 'include' ,要发送Cookie等身份凭证,设置*通配符时,会认为*为普通字符串,而不是通配符,导致允许规则不匹配,无法正常访问跨域资源

简单请求的异常情况完全包含在预检请求的异常情况内,下面将列出预检请求异常错误及解决方法

Access to XMLHttpRequest at 'http://192.168.1.7:3123/api' from origin 'http://192.168.1.7:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

Koa解决方法示例

代码语言:javascript
复制
// ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Origin', ctx.headers['origin'] || '*');

Access to XMLHttpRequest at 'http://192.168.1.7:3123/api' from origin 'http://192.168.1.7:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Koa解决方法示例

代码语言:javascript
复制
ctx.set('Access-Control-Allow-Credentials', true);

Access to XMLHttpRequest at 'http://192.168.1.7:3123/api' from origin 'http://192.168.1.7:3000' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

Koa解决方法示例

代码语言:javascript
复制
// ctx.set('Access-Control-Allow-Headers', '*');
ctx.set('Access-Control-Allow-Headers', ctx.headers['access-control-request-headers'] || '*');

这里就是获取到预检请求中Access-Control-Request-Headers的值,再设置为允许的headers。这样子不代码写死允许哪些headers保证各个服务都可以用

Access to XMLHttpRequest at 'http://xxxxx' from origin 'http://yyyyy' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

这种情况是预检请求发生了重定向,可以试下在请求地址中增加/,比如请求地址为 http://a.cn/api?m=n ,调整请求地址为 http://a.cn/api/?m=n

完整Koa示例代码

代码语言:javascript
复制
ctx.set('Access-Control-Allow-Methods', '*');
ctx.set('Access-Control-Expose-Headers', '*');
// ctx.set('Access-Control-Allow-Origin', '*');
// ctx.set('Access-Control-Allow-Headers', '*');
ctx.set('Access-Control-Allow-Origin', ctx.headers['origin'] || '*');
ctx.set('Access-Control-Allow-Headers', ctx.headers['access-control-request-headers'] || '*');
ctx.set('Access-Control-Allow-Credentials', true);
// console.log('headers:', ctx.headers);
console.log('cookies uin:', ctx.cookies.get('uin'));
ctx.body = { code: 0 };

以上基本罗列所有出错的情况,示例代码为Koa版本,不同的后端服务,获取header头字符串的大小写可能有差异

从安全方面考虑,这种允许任何地址访问的方式,不要使用在生产环境中!

参考资料:

跨源资源共享(CORS)

Access-Control-Allow-Headers

通过fetch看跨域:是谁阻止了跨域请求?

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档