首页IT科技为什么跨域不安全(什么是跨域以及为什么会出现跨域以及跨域的解决方案)

为什么跨域不安全(什么是跨域以及为什么会出现跨域以及跨域的解决方案)

时间2025-06-03 23:30:34分类IT科技浏览5317
导读:1.什么是跨域?...

1.什么是跨域?

跨域:指的是浏览器不能执行其他网站的脚本            。它是由浏览器的同源策略造成的            ,是浏览器对javascript施加的安全限制                  。

• 同源策略:是指协议                  ,域名      ,端口都要相同      ,其中有一个不同都会产生跨域;

跨域举例:

2.为什么会出现跨域?

我们都知道要想访问一个网站                  ,首先要知道这个网站的URL            ,才能够进入该网站      。而URL是由协议            、域名                  、端口组成的(协议      ,浏览器自动填充;域名的端口默认为80                  ,所以通常这两项不用输入)      。而跨域就是说去访问的网站信息中的协议      、域名      、端口号这三者之中任意一个与当前页面的URL地址不同就是跨域                  。即使两个不同的域名指向同一个ip地址            ,也是跨域(即非同源)            。

举个栗子:

一个钓鱼网站的页面通过iframe嵌入了某宝的登录页面,如果没有同源限制                  ,钓鱼网站上的js脚本就可以获取到用户账号和密码      。也就是说                  ,同源限制策略就是限制了一下几种行为:

1.) Cookie                  、LocalStorage 和 IndexDB 无法读取

2.) DOM 和 Js对象无法获得

3.) AJAX 请求不能发送

3.跨域的解决方案

1            、 通过jsonp跨域

2      、 document.domain + iframe跨域

3                  、 location.hash + iframe

4            、 window.name + iframe跨域

5、 postMessage跨域

6                  、 跨域资源共享(CORS)

7                  、 nginx代理跨域

8、 nodejs中间件代理跨域

9            、 WebSocket协议跨域

一                  、 通过jsonp跨域

通常为了减轻web服务器的负载,我们把js      、css            ,img等静态资源分离到另一台独立域名的服务器上                  ,在html页面中再通过相应的标签从不同域名下加载静态资源      ,而被浏览器允许            ,基于此原理                  ,我们可以通过动态创建script      ,再请求一个带参网址实现跨域通信                  。

vue.js解决方案:

this.$http.jsonp(‘http://www.domain2.com:8080/login’, {

params: {},

jsonp: ‘handleCallback’

}).then((res) => {

console.log(res);

})

二            、 document.domain + iframe跨域

此方案仅限主域相同      ,子域不同的跨域应用场景            。

实现原理:两个页面都通过js强制设置document.domain为基础主域                  ,就实现了同域。

1.)父窗口:(http://www.domain.com/a.html)

三                  、 location.hash + iframe跨域 实现原理: a欲与b跨域相互通信            ,通过中间页c来实现                  。 三个页面      ,不同域之间利用iframe的location.hash传值                  ,相同域之间直接js访问来通信                  。

具体实现:A域:a.html -> B域:b.html -> A域:c.html            ,a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信                  ,但c与a同域                  ,所以c可通过parent.parent访问a页面所有对象。

1.)a.html:(http://www.domain1.com/a.html)

2.)b.html:(http://www.domain2.com/b.html) 3.)c.html:(http://www.domain1.com/c.html) 四      、 window.name + iframe跨域 window.name属性的独特之处:name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)            。 五      、 postMessage跨域 postMessage是HTML5 XMLHttpRequest Level 2中的API            ,且是为数不多可以跨域操作的window属性之一                  ,它可用于解决以下方面的问题: a.) 页面和其打开的新窗口的数据传递 b.) 多窗口之间消息传递 c.) 页面与嵌套的iframe消息传递 d.) 上面三个场景的跨域数据传递

用法:postMessage(data,origin)方法接受两个参数

data: html5规范支持任意基本类型或可复制的对象      ,但部分浏览器只支持字符串            ,所以传参时最好用JSON.stringify()序列化                  。

origin: 协议+主机+端口号                  ,也可以设置为"*“      ,表示可以传递给任意窗口      ,如果要指定和当前窗口同源的话设置为            ”/"      。

六                  、 跨域资源共享(CORS)

跨域资源共享(corss-origin resource sharing):CORS需要浏览器和服务器同时支持            。目前所有浏览器都支持该功能                  ,IE浏览器不能低于IE10                  。整个CORS通信过程            ,都是浏览器自动完成      ,不需要用户参与      。对于开发者来说                  ,CORS通信与同源的AJAX通信没有差别            ,代码完全一样      。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息                  ,有时还会多出一次附加的请求                  ,但用户不会有感觉                  。因此,实现CORS通信的关键是服务器            。只要服务器实现了CORS接口            ,就可以跨源通信      。

两种请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)                  。

简单请求

对于简单请求                  ,浏览器直接发出CORS请求            。具体来说      ,就是在Header中增加一个Origin字段。如果浏览器发现跨源AJAX请求是简单请求            ,就自动在头信息之中                  ,添加一个Origin字段                  。

GET /cors HTTP/1.1 Origin: http://easywork.xin //浏览器添加字段      ,说明本次请求来自哪个源(协议+域名+端口)                  。 Host: 119.23.214.114 Accept-Language: en-US Connection: keep-alive User-Agent: Mozilla/5.0…

服务器根据Origin的值决定是否同意这次请求。

如果Origin指定的源在不在后端的许可白名单范围内      ,服务器会返回一个正常的http回应            。浏览器接收后发现                  ,这个response的Header没有包含Access-Control-Allow-Origin字段            ,就知道出错了      ,从而抛出一个错误                  ,被XMLHttpRequest的onerror回调函数捕获                  。这种错误无法通过状态码识别            ,因此HTTP response的状态码有可能是200      。

如果Origin指定的域名在许可的范围内,则服务器返回的相应中                  ,会多出几个头信息字段

Access-Control-Allow-Origin: http://easywork.xin Access-Control-Allow-Credentials: true Access-Control-Expose-Headers: FooBar Content-Type: text/html; charset=utf-8

Access-Control-Allow-Origin:(必须字段)它的值要么是请求时Origin的值                  ,要么是*,表示接受任意域名的请求            。

Access-Control-Allow-Credentials:(可选字段)它是一个bool值            ,表示是否允许发送Cookie                  。默认情况下                  ,Cookie不包括在CORS请求之中      。设为true      ,表示服务器明确许可            ,Cookie可以包含在请求中                  ,一起发给服务器      。CORS请求默认不发送Cookie和HTTP认证信息                  。如果要把Cookie发送到服务器      ,一方面要服务器同意      ,指定Access-Control-Allow-Credentials:true;另一方面                  ,前端必须在AJAX请求中打开withCredentials属性:

var xhr = new XMLHttpRequest(); xhr.withCredentials = true;

注意:如果要发送Cookie            ,Access-Control-Allow-Origin不能设置为*       ,必须指定明确的                  ,与请求网页一致的域名            。同时            ,Cookie依然遵守同源政策,只有用服务器域名设置的Cookie才会上传                  ,其他域名的Cookie并不会上传      。

Access-Control-Expose-Headers:(可选字段)CORS请求时                  ,XMLHttpRequest对象的getResponseHeader(args)方法只能拿到6个基本字段:Cache-Control            、Content-Language      、Content-Type                  、Expires            、Last-Modified、Pragma                  。如果想拿到其他字段,就必须在Access-Control-Expose-Headers`里面指定            。

2. 非简单请求

非简单请求是那种对服务器有特殊要求的请求            ,比如请求方法是PUT或DELETE                  ,或者Content-Type字段的类型是application/json。

非简单请求的CORS请求      ,会在正式通信之前            ,增加一次HTTP查询请求                  ,称为"预检"请求(preflight)                  。浏览器先询问服务器      ,当前网页所在的域名是否在服务器的许可名单之中      ,以及可以使用哪些HTTP动词和头信息字段                  。只有得到肯定答复                  ,浏览器才会发出正式的XMLHttpRequest请求            ,否则就报错。

与JSONP比较

CORS与JSONP的使用目的相同      ,但是比JSONP更强大            。JSONP只支持GET请求                  ,CORS支持所有类型的HTTP请求                  。JSONP的优势在于支持老式的浏览器            ,以及可以向比支持CORS的网站请求数据      。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
java多线程知识(Java多线程(5):CAS) php和php-fpm(PHPCMS和PHP的区别?)