1.同源
如果两个url的协议、域名、端口号完全一致,那么这两个url就是同源的。
举例说明:
https://a.com
https://b.com
域名不同,两者不同源
https://a.com
http://a.com
协议不同,两者不同源
https://a.com
https://a.com:8848
端口号不同,两者不同源
https://a.com/index.html
https://a.com/detail.html
协议相同,域名相同,端口号相同(默认80),路径不同,两者同源
2.同源策略
浏览器规定,如果js运行在源A里,那么就只能获取源A的数据,不能获取源B的数据,既 不允许跨域。
同源策略的目的是为了保护用户的隐私。
3.跨域
突破浏览器同源策略的限制,让不同的源之间可以相互访问数据,就是跨域。
4.CORS 跨域
允许浏览器向跨源服务器发出XMLHttpRequest请求,克服了AJAX只能同源使用的限制。
- CORS需要浏览器和服务器同时支持
- 实现CORS通信的关键是服务器实现了CORS接口
简单请求:
(1)请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
过程:
- 浏览器直接发出CORS请求,在头信息中增加一个Origin字段
Origin: http://api.bob.com
- 如果Origin指定的源在服务器许可范围内,则增加响应头信息,实现跨域
response.setHeader('Access-Control-Allow-Origin','http://frank.com:9990')
- 否则跨域失败
5.JSONP 跨域
当浏览器不支持CORS 跨域时,使用JSONP进行跨域。
举例说明:a.com要访问b.com中friends.json数据。
//b中文件:
window["{{xxx}}"]({{data}}) //friends.js
[{ "name": "jack" }, { "name": "frank" }] //friends.json
/////////////////////////////////////////////////////////////
//b后台程序
//server.js
else if (path === "/friends.js") {
if (request.headers["referer"].indexOf("http://a.com:9999") === 0) {
response.statusCode = 200;
response.setHeader("Content-Type", "text/javascript;charset=utf-8");
const string = fs.readFileSync("./public/friends.js").toString();
const data = fs.readFileSync("./public/friends.json").toString();
const string2 = string
.replace("{{data}}", data)
.replace("{{xxx}}", query.callback);
response.write(string2);
response.end();
//////////////////////////////////////////////////////////////////
//a中文件
//a.js
function jsonp(url){
return new Promise((resolve,reject)=>{
const random='frankcallbackname'+Math.random()
window[random]=(data)=>{
resolve(data)
}
const script=document.createElement('script')
script.src=`${url}?callback=${random}`
script.onload=()=>{
script.remove()
}
script.onerror=()=>{
reject()
}
console.log(script)
document.body.appendChild(script)
})
}
过程:
- a.js定义回调函数,函数名为一随机数,并定义script标签引用friends.js
- b后台程序处理请求,将随机数替换为函数名,friends.json数据替换data
- friends.js执行回调函数'window["{{xxx}}"]{{data}}'
- 请求成功,调用then方法,执行成功函数,得到数据
JSONP 跨域缺点
- 不支持post只支持get
- 调用失败的时不返回HTTP状态码和Header
JSONP 跨域优点
- 兼容IE
- 可以实现跨域