什么是跨域?
跨域就是不同源的数据相互访问,受到浏览器同源策略的限制。
那甚么又是同源策略?
同源策略是浏览器故意设置的一个功能限制,为的是限制来自不同源的域向自己发送请求的时候进行拦截,浏览器这样做的目的是为了保护用户的隐私。
同源的定义:
- 源:window.origin 或 location.origin可以得到当前源
- 源 = 协议 + 域名 + 端口号。
如果两个url的协议域名和端口都完全相同,那么这两个url就是同源的。
例如:
https://qq.com 和 https://www.baidu.com 不同源 【协议相同,域名不同,端口相同】
https://baidu.com 和 https://www.baidu.com 不同源 【协议相同,域名不同,端口相同】
举一个跨域的例子:
http://qq.com下有一个friends.json文件,当我们在http://liang.com 即 localhost:9990里正常使用Ajax去访问http://qq.com下的friends.json文件的时候就会发生如下图所示的错误。即发生了跨域,受到浏览器同源策略的限制。
可能又会有人问,为什么同源策略不会阻止link标签引入的不同源的css文件,以及src引入的js文件呢?
这是因为同源策略限制的是数据的访问,实际上跨域的时候是可以成功访问到文件的,只是浏览器限制了我们对文件的访问;但是浏览器不会限制对这些文件的执行,以上两种情况只是在执行这两种文件,并没有要访问文件里面内容的意思,因此没有甚么影响。
那么我们怎么跨域呢?
方法一: CORS(跨域资源共享)
如果想要跨域共享数据,就得提前声明,告诉浏览器。
在被请求的服务端的响应头里设置Access-Control-Allow-Origin属性值为允许请求的源
如上述例子:在http://qq.com 的 响应头里设置Access-Control-Allow-Origin:liang.com.
详情可看文档:
HTTP访问控制(CORS)developer.mozilla.org但是IE不支持CORS,如果要兼容IE怎么办?还有另一种方法JSONP:
什么是JSONP?我们在跨域的时候由于当前浏览器不支持cors或者其他某些原因不支持cors(跨域资源共享)【即ie不支持通过设置access-allow-origin来实现跨域资源共享】,我们必须使用另外一种方法跨域,于是我们就请求一个js文件 ,这个js文件会执行一个回调,这个回调里面就有我们的数据。回调名字可 以随机形成,以callback参数传递后台,后台一函数执行的形式返回。
- 优点:兼容ie;可以跨域;
- 缺点:由于他是script标签,所以无法读取到ajax那么精确的状态(状态吗、响应头),只知道成功和失败;只能发送get请求,不支持post;
其他方法:postmessage、websocket、nginx、iframe 之后在做补充。