同源策略与CORS

同源策略

同源策略是浏览器保护用户安全上网的重要措施,协议、域名、端口号三者相同即为同源。

不同源下,浏览器不允许js操作Cookie、LocalStorage、DOM等数据或页面元素,也不允许发送ajax请求,同源下则不受影响。

下图是在Chrom控制台中发送ajax跨域请求的报错信息:

图片中黄色部分提示响应被阻止,说明在跨域的情况下,请求依然发送到了服务器且服务器返回了数据,只是被浏览器拦下了。

对于跨域问题可以使用CORS来解决,使用CORS时,HTTP请求分为两种情况:简单请求与复杂请求。

简单请求

满足以下三点即为简单请求:

  • HTTP请求方法为GET、POST或HEAD
  • HTTP请求头只能包含Accept, Accept-Language, Content-Language, Content-TypeLast-Event-ID
  • ContentType的值只能为以下三种:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

复杂请求

除简单请求之外即为复杂请求。浏览器在发送复杂请求前会先发送Preflight request(预检请求),即发送OPTIONS请求。注意是浏览器发送的,用户无感。

预检请求头包含两个特定字段:

  • Access-Control-Request-Method 表示后续请求会用到的HTTP方法,该字段必选
  • Access-Control-Request-Headers 后续请求中所设置的请求头部信息,注意,这里不包含浏览器默认设置的头部字段,如:User-Agent。该字段可不发送。

服务器会检查对预检请求中的OriginAccess-Control-Request-MethodAccess-Control-Request-Headers字段值,并返回正常的HTTP响应。 浏览器根据返回信息判断后续请求是否符合服务器端跨域要求,不符合则抛出错误信息。通过预检请求后,则发送后续请求,此时和简单请求无差别。

服务器配置CORS的几个字段

  • Access-Control-Allow-Origin 必选,设置允许哪些源访问服务器资源
  • Access-Control-Allow-Methods 必选,设置允许哪些HTTP方法
  • Access-Control-Request-Headers 设置HTTP请求头中包含哪些字段,如果浏览器请求包括Access-Control-Request-Headers字段,则必选

以上三个字段为常用字段,其余字段配置参考:CORS policy options

一个问题

上周在ASP.NET Web API 2中使用CORS,报错:The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed。原因是服务器端配置了两次CORS,导致返回了两个Access-Control-Allow-Origin:*但浏览器只允许一个。

经过排查发现在Web.config文件中也配置了CORS,与代码中的配置重复,注释掉之后问题解决。该问题参考了:stackoverflow上的回答。

小结

同源策略是浏览器为保障用户(数据)安全而对JS功能进行一定限制。毕竟HTML与CSS只负责网页结构与样式,不具备操作页面元素及与服务器交互的功能。

离开浏览器环境后跨域问题也就不复存在。

严格的限制会导致一些不便,故同源策略开了几个口子:

  • Cookie共享 子域名可以共享父级域名的cookie
  • 嵌入式资源获取 <script>,<img>,<link>等标签获取资源不受同源策略限制,这也是JSONP实现跨域的原理

常用处理跨域请求的方式有JSONP和CORS:

  • JSONP 需要前后端协作处理且只支持GET请求 不是标准规范 对老式浏览器友好(这里想到了老古董IE:)
  • CORS 支持GET、POST、PUT、DELETE等多种请求 服务器端配置简单且不需要前端写额外的代码 目前主流浏览器均支持CORS规范

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python

flask_socket_io中报错RuntimeError: You need to use the eventlet server. See the Deployment section of t

经测试发现,如果是用uwsgi启动,采用eventlet模式,process只能设置1个,且会造成线程堵塞,如果设置超过1个,也会报上面的错误

2943
来自专栏容器云生态

根据红帽RHEL7官方文档对centos7进行技术剖析(一)

序言:红帽7教学环境介绍 rht-vmctl命令介绍; $ rht-vmctl start desktop     启动desktop虚拟机 $ rht-vmc...

3206
来自专栏张善友的专栏

Enterprise Library 4 缓存快速入门

快速入门使用了一个顶层的处理程序来捕获任何场景中的任何异常。处理程序显示了一个带有异常信息的对话框。 快速入门在构建和运行应用程序之前不需要执行任何安装步骤。...

2209
来自专栏PHP实战技术

初识 Nginx

Nginx 是一个免费的,开源的,高性能的HTTP服务器和反向代理,以及IMAP / POP3代理服务器。 Nginx

2909
来自专栏自由而无用的灵魂的碎碎念

分享:Eclipse 中 drop to frame 的调试技巧

前些天和同事交流调试技巧时,知道了 Eclipse debug 时有个 drop to frame 的技巧。这是我以前不知道的,自己又查了一下这个功能的含义。官...

902
来自专栏Fish

使用cuda-gdb调试cu程序

简要教程 仿佛对于.cu程序的调试是需要关闭x的,所以学习了一下如何用cuda-gdb在tty下调试.cu程序. 1. 对于.cu文件是需要编译好才能调试...

3516
来自专栏张戈的专栏

解决网站404页面返回200状态码问题

好久没打理博客,突然收到 CDN 流量预警,发现平均每天 40G 流量消耗!what?就现在这个访问量,不存在的。看了下 CDN 日志发现有小人一直在请求博客页...

3143
来自专栏超然的博客

JSONP && CORS

  前天面试被问到了跨域的问题,自我感觉回答的并不理想,下面我就分享一下整理后的总结分享给大家

2252
来自专栏张伟博客

ubuntu安装软件和查看已安装软件

2.8K4
来自专栏抠抠空间

爬虫之FileCookieJar

1830

扫码关注云+社区

领取腾讯云代金券