You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
设想这样一种情况:A 网站是一家银行,用户登录以后,A 网站在用户的机器上设置了一个 Cookie,包含了一些隐私信息(比如存款总额)。用户离开 A 网站以后,又去访问 B 网站,如果没有同源限制,B 网站可以读取 A 网站的 Cookie,那么隐私信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
<!--控制台返回结果-->
XMLHttpRequest cannot load http://localhost/city.json.
The 'Access-Control-Allow-Origin' header has a value 'http://segmentfault.com' that is not equal to the supplied origin.
Origin 'http://www.zhihu.com' is therefore notallowed access.
服务器不允许任何跨域请求
<!--控制台返回结果-->
XMLHttpRequest cannot load http://localhost/city.json.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://www.zhihu.com' is therefore not allowed access.
同源策略
1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。
最初,它的含义是指,A 网页设置的 Cookie,B 网页不能打开,除非这两个网页“同源”。所谓“同源”指的是“三个相同”:
协议相同
域名相同
端口相同
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A 网站是一家银行,用户登录以后,A 网站在用户的机器上设置了一个 Cookie,包含了一些隐私信息(比如存款总额)。用户离开 A 网站以后,又去访问 B 网站,如果没有同源限制,B 网站可以读取 A 网站的 Cookie,那么隐私信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
非同源主要由三种行为受限制
什么是跨域
URL1 : http://kangbiao.org/index URL2 : https://kangbiao.org/index
是否跨域 : 是 原因 : 协议不同
URL1 : http://kangbiao.org/index URL2 :http://kangbiao.org:8080/index
是否跨域 : 是 原因 : 端口号不同
URL1 : http://kangbiao.org/index URL2 :https://kangbiao.org/index
是否跨域 : 是 原因 : 主机不同
URL1 : http://kangbiao.org/index URL2 : http://t1.kangbiao.org/index
是否跨域 : 是 原因 : 主机不同
通过上面的比较可以归纳出,跨域是指协议、主机地址、端口号这三个条件只要有一个不同则认为是跨域。
另一个疑问
请求跨域了,那么请求有没有发出去?
跨域并不是请求发不出去,请求能发出去,服务器端能收到请求并返回正常结果,只是被浏览器拦截了
为什么表单可以发起跨域请求,而ajax不可以?
说白了,表单就是提交数据,并不会获取最新的内容,所以可以发起跨域请求。而ajax可以获取响应,浏览器认为这并不安全,所以拦截了响应。
为什么要有跨域限制
Ajax 的同源策略主要是为了防止
CSRF
(跨站请求伪造) 攻击,如果没有 AJAX 同源策略,相当危险,我们发起的每一次 HTTP 请求都会带上请求地址对应的 cookie,那么可以做如下攻击:当我们浏览信息时,看起来获取到了所需要的内容,但是如果有恶意攻击我们是无法用肉眼察觉的,这些攻击会盗取个人信息,隐私
DOM同源策略也一样,如果
iframe
之间可以跨域访问,可以这样攻击:做一个假网站,里面用iframe嵌套一个银行网站 mybank.com。
把iframe宽高啥的调整到页面全部,这样用户进来除了域名,别的部分和银行的网站没有任何差别。
这时如果用户输入账号密码,我们的主网站可以跨域访问到http://mybank.com的dom节点,就可以拿到用户的输入了,那么就完成了一次攻击。
解决跨域
CORS
CORS 是一个 W3C 标准,全称是跨域资源共享(Cross-origin resource sharing),它允许浏览器向跨源服务器,发出XMLHttpRequest请求。
CORS跨域判定流程
Access-Control-Allow-origin
字段,若配置过域名,则返回Access-Control-Allow-origin + 对应配置规则里的域名的方式
。Access-Control-Allow-origin
字段做匹配,若无该字段,说明不允许跨域,从而抛出一个错误;若有该字段,则对字段内容和当前域名做比对,如果同源,则说明可以跨域,浏览器接受该响应;若不同源,则说明该域名不可跨域,浏览器不接受该响应,并抛出一个错误。服务器是否指定跨域请求
服务器允许跨域请求,但是 Origin 指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含
Access-Control-Allow-Origin
字段,就知道出错了,从而抛出一个错误,被 XMLHttpRequest的onerror 回调函数捕获。注意,这种错误无法通过状态码识别,因为 HTTP 回应的状态码有可能是200。服务器不允许任何跨域请求
简单请求
条件:
使用
GET、POST、HEAD
其中一种请求方法。Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值
application/x-www-form-urlencoded、multipart/form-data、text/plain
请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器
XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。 请求中没有使用 ReadableStream 对象。
对于简单请求,浏览器直接发起 CORS 请求,具体来说就是服务器端会根据请求头信息中的
origin
字段(包括了协议 + 域名 + 端口),来决定是否同意这次请求。如果
origin
指定的源在许可范围内,服务器返回的响应,会多出几个头信息字段:非简单请求
请求方法是
put
或delete
,或者content-type
的类型是application/json
非简单请求的 CORS 请求,会在正式通信之前,使用
OPTIONS
方法发起一个预检(preflight)请求到服务器,浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。预请求头部 :
一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样了
JSONP
JSONP 的原理就是利用
<script>
标签的 src 属性没有跨域的限制,通过指向一个需要访问的地址,由服务端返回一个预先定义好的 Javascript 函数的调用,并且将服务器数据以该函数参数的形式传递过来,此方法需要前后端配合完成。 (只限于get请求)Nginx服务器代理
浏览器有跨域限制,但是服务器不存在跨域问题,所以可以由服务器请求所要域的资源再返回给客户端。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
The text was updated successfully, but these errors were encountered: