跨域实现资源共享
前置知识
- 什么是源(Origin)?
Web内容的源由用于访问它的 URL 的方案(协议),主机(域名)和端口定义; - 什么是同源?
只有当方案,主机和端口都匹配时,两个对象具有相同的源;同源,因为相同的方案(http)和主机(example.com)
http://example.com/app1/index.html
http://example.com/app2/index.html
同源,因为默认情况下服务器通过 80 端口交付 HTTP 内容
http://Example.com:80
http://example.com - 什么是同源策略?
同源策略 是一个重要的安全策略,它用于限制一个 origin 的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
简言之:不同源无法正常地互相访问资源。
什么是跨域?
在非同源的URL中访问资源
JSONP 实现跨域
虽然我们不能跨域访问 json 文件,但是可以访问 js 文件
假设源 A 上有一个数据文件 a.json
我们想让源 B 也能访问它,首先创建一个 b.js 文件
// b.js
window.xxx({{"123"}})
然后在服务端这样写:
if(path === '/b.js'){
if(request.headers['referer'].indexOf(B)===0){
response.statusCode = 200
response.setHeader("Content-Type","text/javascript;charset=utf-8")
const string = fs.readFileSync("b.js的地址").toString()
const data = fs.readFileSync("a.json的地址").toString()
const string2 = string.replace("{{"123"}}",data)
response.write(string2)
response.end()
}else{
response.statusCode = 404
response.end()
}
}
利用request.headers['referer']
来判断请求响应的是不是允许的源
然后把json里的数据赋给js文件就可以了
CORS 实现跨域
跨源HTTP请求的一个例子:运行在 https://domain-a.com
的 JavaScript 代码使用 XMLHttpRequest
来发起一个到 https://domain-b.com/data.json
的请求。
出于安全性,浏览器限制脚本内发起的跨源HTTP请求。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。
-
简单请求
某些请求不会触发 CORS 预检请求。称这样的请求为“简单请求”,若请求满足所有下述条件,则该请求可视为“简单请求”:1.使用
GET
POST
HEADER
方法之一
2.HTTP 地头部信息不超过以下几种:Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
-
非简单请求
凡是不同时满足上面两个条件,就属于非简单请求。
使用方法
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
} else {
xhr = null;
}
return xhr;
}
window.onload = function () {
var oBtn = document.getElementById('btn1');
oBtn.onclick = function () {
var xhr = createCORSRequest("get", "http://wpdic.com/cors.php");
if (xhr) {
xhr.onload = function () {
var json = JSON.parse(xhr.responseText);
alert(json.a);
};
xhr.onerror = function () {
alert('请求失败.');
};
xhr.send();
}
};
};
服务器端
header('content-type:application:json;charset=utf8');
header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:GET,POST');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers:x-requested-with,content-type');
-
Access-Control-Allow-Origin:*
表示允许任何域名跨域访问,如果需要指定某域名才允许跨域访问,只需把Access-Control-Allow-Origin:*
改为Access-Control-Allow-Origin:允许的域名
; -
`Access-Control-Allow-Methods:GET,POST 规定允许的方法,建议控制严格些,不要随意放开DELETE之类的权限
-
Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
CORS和JSONP的应用区别
JSONP的主要优势在于对浏览器兼容较好;虽然目前主流浏览器支持CORS,但IE10以下不支持CORS;
JSONP只能用于获取资源(即只读,类似于GET请求);CORS支持所有类型的HTTP请求,功能完善;
CORS功能更加强大。