我们为什么需要用到跨域?
当我们从一个域名请求另外一个域名下的信息时,浏览器会默认阻止我们的请求。
放心这并不是一个错误,而是基于浏览器的一个安全策略。这个策略的名字叫做同源策略。
所谓同源是指,域名,协议,端口都必须相同。假如说,你想在你本地上的随便一个html文件上去访问其他域名里的内容,浏览器会阻止你,让你无法获取到数据。
如何解决跨域:
这里介绍目前主流的前端解决跨域的方案:
1.jsonp
2.CORS
3.在webpack中通过配置devServer的方式跨域
4.通过集成环境(本地模拟服务器)跨域
5.使用chrome浏览器跨域
6.在小程序中解决跨域问题
7.在cli项目中解决跨域问题
第一种方式:jsonp跨域
所谓jsonp就是在服务器端会给你输出一个字符串函数,你通过在本地定义一个同样名字的函数去执行就可以了。如果你不了解后端,也没有关系,你可以直接复制下面的例子来输出接口数据。
原生javascript跨域的例子:
<style type="text/css">
#con { width: 300px;height: 50px;}
#box div{ width: 300px; height: 30px; border: 1px solid red; }
</style>
<input type="text" id="con" value="" />
<div id="box"></div>
<script type="text/javascript">
var con=document.getElementById("con");
var box=document.getElementById("box");
var script1=null;
function callback(str){
var json=str.s;
for (var i=0; i<str.s.length;i++){
box.innerHTML+="<div>"+str.s[i]+"</div>"
}
}
con.onkeyup=function(){
box.innerHTML="";
if(script1){
document.body.removeChild(script1);
}
script1=document.createElement("script");
script1.src="[http://suggestion.baidu.com/su?cb=callback&wd="+con.value;](http://suggestion.baidu.com/su?cb=callback&wd=)
document.body.appendChild(script1);
};
</script>
jquery jsonp跨域的例子:
$.ajax({
async:false, // 是否是同步请求
url:"[http://ad.bjnews.com.cn/service/getad?pid=1](http://ad.bjnews.com.cn/service/getad?pid=1)",// 地址
type:"GET", // 请求方式
dataType:"jsonp", // 请求的数据类型
jsonp: 'callback', // callback的函数名
jsonpCallback:"callback_adservice",
data: {}, // 你要发送的数据 内容是名值对形式的
success:function(data){
alert(data)
},
//诊断错误类型
error:function(jqXHR,textStatus,errorThrown){
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
}
})
第二种方式:跨域资源共享—CORS
跨源资源共享(CORS)是通过客户端+服务端协作声明的方式来确保请求安全的。服务端会在HTTP请求头中增加一系列HTTP请求参数(例如Access-Control-Allow-Origin等),来限制哪些域的请求和哪些请求类型可以接受,而客户端在发起请求时必须声明自己的源(Orgin),否则服务器将不予处理,如果客户端不作声明,请求甚至会被浏览器直接拦截都到不了服务端。服务端收到HTTP请求后会进行域的比较,只有同域的请求才会处理。
cors前端代码示例:
function getHello() {
var xhr = new XMLHttpRequest();
xhr.open("post", "[http://b.example.com/Test.ashx](http://b.example.com/Test.ashx)", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 声明请求源
xhr.setRequestHeader("Origin", "[http://a.example.com");](http://a.example.com/)
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var responseText = xhr.responseText;
console.info(responseText);
}
}
xhr.send();
}
第三种方式:通过npm安装webpack-dev-server
如果你想要使用webpack-dev-server,首先你得通过webpack在你本地构建一个项目,至于webpack构建项目的方法本文不过多阐述,本文只讲解如何跨域。
安装方法:
npm install webpack-dev-server -S-d
然后打开你的package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"watch": "webpack --watch",
"dev": "webpack-dev-server"
},
加上这句,然后当你通过dev命令运行项目的时候,跨域已经没问题了。
npm run dev
第四种方式:通过集成环境跨域
首先我们不能跨域,很大原因是因为我们是本地浏览器直接打开的。
如果我们给本地安装一套服务器的环境,然后通过ip地址访问,就可以直接解决问题。
其实现在很多开发工具里面已经自带了运行环境,本文只通过hbuilder来演示:
当我们预览页面的时候,会自动开启一个8848端口来为跨域提供服务。
另外,我们还可以通过安装一些集成环境来实现跨域。比如:
我们可以把静态页面放到phpstudy的www目录下,然后通过phpstudy默认的域名来访问页面,一样可以实现跨域。
第五种方式:通过chrome浏览器插件跨域
打开chrome插件商店搜索:Allow CORS: Access-Control-Allow-Origin 0.1.0
安装完毕以后,使用chrome访问页面即可完成跨域。
第六种方式:在小程序中解决跨域问题
小程序中有两个地方需要注意:
第一你的网址需要是https中的服务器,或者是你的开发者平台上的安全域名。第二如果你的php5.5中设置了表单头,你在小程序中也需要设置一个header。
wx.request({
url: '[http://www.dangyunlong.com/api/SmsDemo.php](http://www.dangyunlong.com/api/SmsDemo.php)',
data: {
tel:tel
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
method: "POST",
success: function (res) {
//console.log(res)
that.setData({
cCode: res.data
});
console.log(that.data.cCode)
}
})
第七种方式:在cli项目中解决跨域问题
这里以vuecli为例:
打开config下的index.js
proxyTable: {
'/apiName': {
target: '[http://www.dangyunlong.com/](http://www.dangyunlong.com/)',
changeOrigin: true,
pathRewrite: {
'^/dangyunlong': ''
}
}
},
注意这里的“apiName”跟你在ajax中请求的需要是一样的。
调用的时候“/”可以省略。