前端ajax跨域最全解决方案

我们为什么需要用到跨域?


ajax常见跨域问题

当我们从一个域名请求另外一个域名下的信息时,浏览器会默认阻止我们的请求。
放心这并不是一个错误,而是基于浏览器的一个安全策略。这个策略的名字叫做同源策略。
所谓同源是指,域名,协议,端口都必须相同。假如说,你想在你本地上的随便一个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来演示:

hbuilder提供的8848钛合金预览地址

当我们预览页面的时候,会自动开启一个8848端口来为跨域提供服务。

另外,我们还可以通过安装一些集成环境来实现跨域。比如:


phpstudy是php的集成环境

我们可以把静态页面放到phpstudy的www目录下,然后通过phpstudy默认的域名来访问页面,一样可以实现跨域。

第五种方式:通过chrome浏览器插件跨域


打开chrome插件商店搜索:Allow CORS: Access-Control-Allow-Origin 0.1.0


chrome浏览器提供大量的开发者插件

安装完毕以后,使用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中请求的需要是一样的。
调用的时候“/”可以省略。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容