跨域:
从一个域名的网页去请求另一个域名的资源 比如从淘宝页面去请求拼多多页面的资源,一般是不允许的,浏览器为了js的安全做出的限制----同源策略。那么跨域就是只要 协议,域名,端口有任何一个不同就可以实现跨域。
同源:就是 域名 端口 协议 均相同
那么域名,端口,协议是指什么呢?
http://www.aaa.com:8080/bb.html
协议 子域名 域名 端口
http://www.aaa.com:8080/bb.html调用http://www.aaa.com:8080/cc.html (非跨域)
http://www.aaa.com:8848/bb.html调用http://www.aaa.com:8080/cc.html (跨域 端口号不同)
http://www.bbb.com/bb.html调用http://www.aaa.com/cc.html (跨域 域名不同)
http://qqq.aaa.com/bb.html调用http://eee.aaa.com/cc.html (跨域 子域名不同)
https://www.aaa.com/bb.html调用http://www.aaa.com/cc.html (跨域 协议不同)
ps:localhost和127.0.0.1都是指向本机,但是也属于跨域
执行js脚本时,检查脚本是哪个页面的,如果不是同源不会执行。
限制跨域是为了安全问题,有时是为了方便去访问不同的资源,例如一个公司里面有不同的子域,为了方便取不同子域取要用的资源。
跨域的方法
1> 跨域资源共享(CORS)
CORS(Cross-Origin Resource Sharing) 跨域资源共享,浏览器与服务器共同是通过HTTP头部沟通的。服务器端通过CORS设置Access-Control-Allow- Origin进行的,浏览器得到相应的设置,就可以允许Ajax进行跨域访问。在后台加上允许的域名请求就可以实现跨域访问。
//指定允许其他域名访问 'Access-Control-Allow-Origin:*'//或指定域 //响应类型 'Access-Control-Allow-Methods:GET,POST' //响应头设置 'Access-Control-Allow-Headers:x-requested-with,content-type'
2>通过jsonp跨域
JSONP由回调函数和数据组成,响应时调用函数,然后数据传入回调函数中的JSON中
jsonp原理 :通过script标签引入一个js文件,js加载成功后执行url参数中指定的函数,把需要的json数据作为参数传入,jsonp与服务器端的页面相互配合。(js松台加载script文件,同事定义一个callback函数给script执行)
js中,直接用XMLHttpRequest
请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。
JSONP的优缺点
JSONP的优点是:兼容性好
JSONP的缺点则是:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JS
调用的问题。
CORS和JSONP对比
CORS与JSONP相比,无疑更为先进、方便和可靠。
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)。
JSONP跨域例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
// jsonp 技术
// 利用script的src 没有同源策略的限制,返回的函数名(数据格式)
<body>
//此处可写你要的数据显示在页面上的哪内容
</body>
<script>
function jsonp(url){
return new Promise((resolve,reject)=>{
// 01创建一个script标签
var script = document.createElement("script");
// 创建一个随机的callback函数名
var callback = "callback"+new Date().getTime();
// 如果url里面不包含?pre就是?否则是空
var pre = url.indexOf('?')==-1?'?':'';
// 拼接url
url = url+pre+"&callback="+callback;
// 设置src;
script.src = url;
// 插入到body标签
document.body.appendChild(script);
// 02创建一个函数
window[callback] = function(data){
// 移除script标签
// document.body.removeChild(script);
resolve(data);
}
// 如果失败
script.onerror = function(err){
// 返回错误信息
reject(err);
}
})
}
// 通过ip来获取地址
var url1 = "url";
// 通过地址获取具体想要的内容地址
var url2 = "url";
jsonp(url1)
.then(res=>{
// 执行jsonp 获取想要的数据
return jsonp(url2+``);
})
.then(res=>{
//想要数据的字符串
var str = '';
//获取你要插入到哪的标签
var p = document.querySelector(".tip");
// 设置html内容
p.innerHTML = str;
})
.catch(err=>{
console.log(err);
})
</script>
</html>
ps:有的是通过自己理解的话总结的
故不积跬步,无以至千里;不积小流,无以成江海。(劝学)