跨域问题

2016-12-21

同源策略

什么是同源,满足三个条件相同

Ps. IE例外:不考虑端口;Trust Zones(可信任的域)的域名可以看作是同源

同源策略的限制

  • 通常允许进行跨域写操作(Cross-origin writes)。例如链接(links),重定向以及表单提交。
  • 通常允许跨域资源嵌入(Cross-origin embedding)。就是跨域标签了<scipt>,<link>,<img>,<video>,<object>,<iframe>
  • 通常不允许跨域读操作(Cross-origin reads)。但常可以通过内嵌资源来巧妙的进行读取访问。

如何阻止跨源访问

  • 阻止跨域写操作,只要检测请求中的一个不可测的标记(CSRF token)即可,这个标记被称为Cross-Site Request Forgery (CSRF) 标记。必须使用这个标记来阻止页面的跨站读操作。
  • 阻止资源的跨站读取,需要保证该资源是不可嵌入的。阻止嵌入行为是必须的,因为嵌入资源通常向其暴露信息。
  • 阻止跨站嵌入,确保你得资源不能是以上列出的可嵌入资源格式。多数情况下浏览器都不会遵守Conten-Type消息头。例如,如果你在<script>标签中嵌入HTML文档,浏览器仍将HTML解析为Javascript。当你的资源入口不是指向你的网站, 你同样可以使用CSRF token阻止它嵌入.

document.domain

如果是父子域跨域的情况,可以通过修改document.domain实现父子域同源

如站点store.company.com, 需要访问company.com/api

1
document.domain = 'company.com'

(待验证)

HTTP控制访问CORS

简单请求

如:get一个数据

post也可以,但是Content-Type只能是这三种之一

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

预请求

先发一个options请求,再发正式请求

如:上传文件,想要使用自定义的请求头,如:x-modified

响应头说明

Access-Control-Allow-Origin

允许来自哪些域的请求

出于安全性的考虑,如果客户端xhr指定了withCredentials=true,那么这个值是不能为*,必须指定有哪些域可访问的,确保了登陆态只能给我事前设置好的站点,

Access-Control-Expose-Headers

指定浏览器可以得到服务器的那些自定义的响应头信息,在预请求中,而不是正式请求,这和Access-Control-Allow-Headers是不一样的,这些头预请求的响应头,而不是正式请求的请求头

Access-Control-Max-Age

预请求的结果的有效期是多少,单位(秒)

浏览器关掉后就无效了,应该是这样,待验证

Access-Control-Allow-Credentials

首先这个响应头的值是true或false,如果是true,服务端才把响应数据返回给客户的,否则不返回

服务端是会根据客户端传过来的cookie判断身份信息是否有效,然后决定返回true还是false??

客户端xhr中的withCredentials属性可以决定客户端是不是要把cookie信息带上给服务端

在用一个站点下使用withCredentials属性是无效的。

Access-Control-Allow-Methods

告诉客户端,服务端同意这些请求的方式,比如:get post options

Access-Control-Allow-Headers

预请求中指定服务器在正式的请求中会识别哪些请求头,就是预请求服务同意了哪些header,告诉客户端可以发起Access-Control-Request-Headers

请求头说明

Origin

告诉服务器端,这个请求的来源是哪里,这个值当然就是请求当前所处的域,不包含任何路径信息

Access-Control-Request-Method

告诉服务端,实际请求的方式是什么

Access-Control-Request-Headers

告诉服务端,自定义的header是哪些

兼容性

移动端可以认为全兼容

PC端,Internet Explorer 8 和 9 通过 XDomainRequest 对象来实现CORS,其他也都ok