同源策略
在控制台输入 window.origin
源=协议+域名+端口
协议 +域名+端口号 完全一致 才是同源
浏览器不允许跨域
同源策略是限制的数据访问,我们并看不见里面的数据。
能引用这个js 但是不能读取里面的数据
举例(省略http协议)
假设frank.com/index.html引用了cdn.com/1.js
那么就说{1.js运行在源frank.com里 }
注意这跟cdn.com没有关系,虽然1.js从它那下载
所以1.js就只能获取frank.com的数据
不能获取1.frank.com或者qq.com的数据
目的
为了保护用户隐私
举个例子:
假设有一个kang.com 网站和qq.com网站文件夹状况如下

在没有使用跨域的状态下,如果kang.com 想使用 qq.com里面的friends.json 。是无法那到里面的相关数据。
会报如下错误

这里的请求是发成功了的,但是没有拿到数据
实现跨域
CORS
在server.js里面添加
response.setHeader("Access-Control-Allow-Origin", "允许的网址")
代码展示:
if(path === "/friends.json") {response.statusCode = 200// 允许跨域访问response.setHeader("Access-Control-Allow-Origin", "http://kang.com:9999")response.setHeader("Content-Type", "text/json;charset=utf-8")response.write(fs.readFileSync("./public/friends.json"))response.end()}
jsonp
我们在跨域的时候由于当前浏览器不支持CORS,我们必须使用另一种方式来跨域
于是我们就请求一个js文件,js文件会执行一个回调,回调里面就有个数据。
回调里面的名字可以随机生成的,一个随机数,这个名字再以callback的参数传给后台
后台会吧函数再次返回给我们并执行。
优点:
- 兼容IE
- 可以跨域
缺点
- 由于它是script标签 不能像AJAX读取到状态码和请求头,只知道成功和失败,
- 由于它是script标签 只能发GET请求,不支持POST。
代码展示:
// 服务器里面的代码if (path === "/friends.js") {if (request.headers["referer"].indexOf("http://kang.com:9999") === 0) {response.statusCode = 200response.setHeader("Content-Type", "text/javascript;charset=utf-8")const string = "window['{{xxx}}']({{data}})"const data = fs.readFileSync("./public/friends.json").toString()const string2 = string.replace("{{data}}", data).replace("{{xxx}}", query.callback)response.write(string2)response.end()} else {request.statusCode = 404response.end()}}
// jsonp 代码 封装后的function jsonp(url) {return new Promise((resolve, reject) => {const random = "kangJSONPCallbackName" + Math.random()window[random] = (data) => {console.log(data)}// 创建script标签并引用链接const script = document.createElement("script")script.src = `${url}?callback=${random}`// 加载完后就删除script标签script.onload = () => {script.remove()}script.onerror = () => {reject()}// 将script插入body里面document.body.appendChild(script)})}// 输入可以跨域的地址jsonp("http://qq.com:8888/friends.js").then((data) => {console.log(data)})
其他疑问
为什么a.qq.com访问qq.com也算跨域?
答:因为历史上,出现过不同公司共用域名,a.qq.com和qq.com不一定是同一个网站,浏览器谨慎起见,认为这是不同的源
为什么不同端口也算跨域?
答:原因同上,一个端口一个公司。记住安全链条的强度取决于最弱一环,任何安全相关的问题都要谨慎对待
为什么两个网站的IP是一样的,也算跨域?
答:原因同.上,IP可以共用。
为什么可以跨域使用CSS、JS和图片等?
答:同源策略限制的是数据访问,我们引用CSS、JS和图片的时候,其实并不知道其内容,我们只是在引用。
