同源策略及跨域访问

一、同源策略(Same-origin policy

       是由网景公司(Netscape)提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都会使用这个策略。该策略要求一个域 (origin)的脚本,在未经允许的情况下,不得通过DOM读取另一个域的文档 (document) 的内容或属性。

       同源策略中的同源,指的是协议、host、端口相同。同源下的文档内容及属性可以共享,不同源下的文档内容及属性在未经允许时不可以直接获取。对于js脚本有限制,主要表现在三点:

       1、无法用js读取非同源的Cookie、LocalStorage和IndexDB【如果某恶意网站通过js拿到了用户cookie中的登录账号和密码,然后伪造成用户请求去获取敏感数据】;

       2、无法用js获取非同源的DOM【如果某恶意网站将银行等的登录页面嵌在自己页面上伪造成和银行一样的网页,用户不留心网址或网址只是一个字母之差,那么用户在输入账号和密码登录,该恶意网站就会得到用户输的账号和密码】;

       3、无法用js发送非同源的AJAX请求 。更准确的说,js可以向非同源的服务器发请求,但是服务器返回的数据会被浏览器拦截。【和1结合起来伪造成用户请求去获取敏感数据】

二、不受同源策略限制的情况

       1、页面中的超链接,点击可以访问其他不同源的页面;

       2、表单提交,不同源的页面可以相互提交表单数据;

       3、引入到页面的资源,比如引入js文件,图片或者CSS文件等;

三、规避同源策略的方法

    1、document.domain;

    2、跨文档消息传递 (cross-document messaging);

    3、JSONP (JSON with padding);

    4、WebSocket;

    5、跨域资源共享 (Cross-Origin Resource Sharing, CORS);

       浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。只要同时满足以下两大条件,就属于简单请求。

       1>请求方法是以下三种方法之一:

              HEAD

              GET

              POST

       2>HTTP的头信息不超出以下几个字段:

              Accept

              Accept-Language

              Content-Language

              Last-Event-ID

              Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。浏览器对这两种请求的处理是不一样的:

       简单请求

       1>在请求中需要附加一个额外的Header:Origin,它包含了请求页面的源信息(协议、域名和端口),以便服务器根据这个头部信息来决定是否给予响应;

       2>如果服务器认为这个请求可以接受,就在响应Header:Access-Control-Allow-Origin中发回相同的源信息(如果是公共资源,可以发回 * );

       3>如果响应没有这个Header:Access-Control-Allow-Origin或者Access-Control-Allow-Origin中允许的源信息与请求的Header:Origin不匹配,浏览器就会驳回请求。

       如果请求需要包含Cookie信息,ajax请求需要设置xhr的属性withCredentials为true,服务器需要设置响应Header:Access-Control-Allow-Credentials: true。

       非简单请求

       1>浏览器在发送真正的请求之前,会先发送一个Preflight请求给服务器,这种请求使用OPTIONS方法,发送下列Header:

              Origin:与简单请求相同;

              Access-Control-Request-Method:请求自身使用的方法;

              Access-Control-Request-Headers:(可选)自定义的头部信息,多个头部以逗号分隔。

       2>发送这个请求后,服务器决定是否允许这种类型的请求。服务器通过在响应中发送如下Header与浏览器进行沟通

              Access-Control-Allow-Origin:与简单请求相同。

              Access-Control-Allow-Methods:允许的方法,多个方法以逗号分隔。

              Access-Control-Allow-Headers:允许的头部,多个方法以逗号分隔。

              Access-Control-Max-Age:将这个Preflight请求缓存多长时间(以秒表示)。

       一旦服务器通过Preflight请求允许该请求之后,以后每次浏览器正常的CORS请求,就都跟简单请求一样了。

发布了108 篇原创文章 · 获赞 31 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/lzghxjt/article/details/99193272