摘要:关于跨域为什么会有跨域我们得先了解下同源策略。简而言之,同协议同域名同端口号什么是跨域跨域就是采取技术方案突破同源策略的限制,实现不同域之间交互请求响应。
关于跨域 why?
为什么会有跨域?
我们得先了解下 ==同源策略(SOP, Same Origin Policy)==。
浏览器出于安全方面的考虑,只能访问与包含它的页面位于同一个域中的资源,该策略为通信设置了“相同的协议、相同的域、相同的端口”这一限制。试图访问上述限制之外的资源,都会引发安全错误。这种安全策略可以预防某些恶意行为。
简而言之,
同协议 Same Protocol
同域名 Same Hostname
同端口号 Same Port
Same Protocol && Same Hostname && Same Port
What?什么是跨域?
==跨域就是采取技术方案突破同源策略的限制,实现不同域之间交互(请求响应)。==
How?那么如何实现跨域呢?
有以下几种方法。
==方法一==
CORS (Cross-Origin Resource Sharing,跨域源资源共享),是一种ajax跨域请求资源的方式,支持现代浏览器,IE支持10以上,通过XMLHttpRequest实现Ajax通信的一个主要限制就是同源策略。
CORS是W3C的一个工作草案,定义了在必须访问跨境资源时,浏览器和服务器该如何沟通。CORS的基本思想,就时使用自定义的HTTP头部让浏览器和服务器进行沟通,从而决定请求或者响应应该成功还是失败。
实现思路:使用XMLHttpRequest发送请求时,浏览器会给该请求自动添加一个请求头:Origin。服务器经过一系列处理,如果确定请求来源页面属于白名单,则在响应头部加入首部字段:Access-Control-Allow-Origin。浏览器比较请求头部的Origin 和响应头部的 Access-Control-Allow-Origin是否一致,一致的话,浏览器得到响应数据。如果服务器没有设置Access-Control-Allow-Origin 或者这个头部源信息不匹配,浏览器就会驳回请求。
模拟CORS的实现
步骤1.
如何伪装一个网站(在本地)?
1.编辑hosts文件
苹果mac: 直接在git bash上输入命令行操作即可 “sudo vi /etc.hosts” ,或者下载一些图形界面应用软件直接修改。
Windows操作系统:
win键(四个方块的键)+ R = 弹开运行窗口
复制该文件路径 c:windowssystem32driversetc
选中hosts文件,右键-属性-安全-选择组或用户名(添加修改保存的权限的对象)- 编辑 - 再次选择组或用户名(添加修改保存的权限的对象 - 勾选权限(选项在此不表)
打开hosts文件,写入 127.0.0.1 localhost;127.0.0.1 bai.com;127.0.0.1 google.com;可以写入你任何你想模拟的网站,按照这种对应关系格式即可, ip地址+域名。
步骤2.
所需工具
node.js && git bash(模拟服务器),一个简单的html页面里面有个跨域请求的Ajax通信。
Google
hello world
//nodeJS模拟后端响应CORS的实现
var http = require("http");
var fs = require("fs");
var url = require("url");
var path = require("path");
http.createServer(function(req, res){
var urlObj = url.parse(req.url, true)
switch (urlObj.pathname){
case "/getNews":
var news = ["NBA Break News","CBA Break News"]
//CORS的实现
res.setHeader("Access-Control-Allow-Origin","http://google.com:8080")
/*res.setHeader("Access-Control-Allow-Origin","*")
服务器设置公用接口
*/
res.end(JSON.stringify(news));
break;
case "/" :
if(urlObj.pathname == "/") {
urlObj.pathname += "index.html"
}
default:
var filePath = path.join(__dirname, urlObj.pathname);
fs.readFile(filePath,"binary", function(error, fileContent){
if(error){
console.log("404")
res.writeHeader(404, "not found")
res.end("404,not found
")
}else {
res.write(fileContent, "binary")
}
})
}
}).listen(8080);
上面代码就是CORS实现的过程。
在本地修改hosts文件,127.0.0.1 google.com, 页面的url为 http://google.com:8080。
在title为google的页面上添加一个ajax请求,该请求以get方法会向baiduServer的端口("http://baidu.com:8080/getNews")发送一个请求。
浏览器会给请求头加上Origin: http://google.com:8080, Request URL: http://baidu.com:8080/getNews。
baiduServer后端,响应头添加首部字段。Access-Control-Allow-Origin: http://google.com:8080。 表明该服务器(baiduServer)接受请求并给予响应。
浏览器比较请求头部的Origin 和响应头部的 Access-Control-Allow-Origin是否一致,一致的话,浏览器得到响应数据。如果服务器没有设置Access-Control-Allow-Origin: http://google.com:8080 或者这个头部源信息不匹配,浏览器就会驳回请求。
当然服务器也可以设置公用接口, res.setHeader("Access-Control-Allow-Origin","*")
服务器设置公用接口, 任何人都可以使用该服务器这个端口的数据。
==方法二==
JSONP,是JSON with padding的简写(填充式JSON或参数式JSON)。
JSONP的原理,通过动态 -->