• ajax处理跨域有几种方式


    一、什么是跨域

    同源策略是由Netscape提出的著名安全策略,是浏览器最核心、基本的安全功能,它限制了一个源(origin)中加载文本或者脚本与来自其他源(origin)中资源的交互方式
    ,所谓的同源就是指协议、域名、端口相同。
    当浏览器执行一个脚本时会检查是否同源,只有同源的脚本才会执行,如果不同源即为跨域

     二、出现跨域问题的情况

    由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问。

    比如说你的网站域名是aaa.com,想要通过AJAX请求bbb.com域名中的内容,浏览器就会认为是不安全的,所以拒绝访问。

    会出现跨域问题的几种情况:

    探讨跨域请求资源的几种方式

    四、处理跨域的方法2 -- JSONP

     原理
            其本质是利用了标签<img>||<script>具有可跨域的特性, 由服务端返回一个预先定义好的Javascript函数的调用,并且将服务器数据以该函数参数的形式传递过来, 此方法需要前后端配合完成。但是JSONP只支持 “GET” 请求,但不支持 “POST” 请求。

    服务端JSONP格式数据

    jsonp.php 文件代码

    <?php
    header('Content-type: application/json');
    //获取回调函数名
    $jsoncallback = htmlspecialchars($_REQUEST ['jsoncallback']);
    //json数据
    $json_data = '["customername1","customername2"]';
    //输出jsonp格式的数据
    echo $jsoncallback . "(" . $json_data . ")";
    ?>

    客户端页面完整代码
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>JSONP 实例</title>
    </head>
    <body>
        <div id="divCustomers"></div>
        <script type="text/javascript">
    function callbackFunction(result, methodName)
            {
                var html = '<ul>';
                for(var i = 0; i < result.length; i++)
                {
                    html += '<li>' + result[i] + '</li>';
                }
                html += '</ul>';
                document.getElementById('divCustomers').innerHTML = html;
            }
    </script>
    <script type="text/javascript" src="http://www.runoob.com/try/ajax/jsonp.php?jsoncallback=callbackFunction"></script>
    </body>
    </html>

     
    jQuery 使用 JSONP
    缺点:

      1、这种方式无法发送post请求(这里

      2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

    跨域的几种方式

    在项目中可能会需要在一个域名下请求另外一个域名的资源,下面我们来探讨下跨域的几种实现方式

    1、jsonp

    最常见的一种跨域方式,其背后原理就是利用了script标签不受同源策略的限制,在页面中动态插入了script,script标签的src属性就是后端api接口的地址,并且以get的方式将前端回调处理函数名称告诉后端,后端在响应请求时会将回调返还,并且将数据以参数的形式传递回去。

    前端:

    //http://127.0.0.1:8888/jsonp.html
    var script = document.createElement('script');
          script.src = 'http://127.0.0.1:2333/jsonpHandler?callback=_callback'
          document.body.appendChild(script);      //插入script标签
          //回调处理函数 _callback
          var _callback = function(obj){
              for(key in obj){
                console.log('key: ' + key +' value: ' + obj[key]);
              }
          }

    后端:

    //http://127.0.0.1:2333/jsonpHandler
    app.get('/jsonpHandler', (req,res) => {
      let callback = req.query.callback;
      let obj = {
        type : 'jsonp',
        name : 'weapon-x'
      };
      res.writeHead(200, {"Content-Type": "text/javascript"});
      res.end(callback + '(' + JSON.stringify(obj) + ')');
    })

    在jsonp.html中打开控制台可以看到返回数据的输出:


    jsonp.png

    2、CORS

    Cross-Origin Resource Sharing(跨域资源共享)是一种允许当前域(origin)的资源(比如html/js/web service)被其他域(origin)的脚本请求访问的机制。
    当使用XMLHttpRequest发送请求时,浏览器如果发现违反了同源策略就会自动加上一个请求头:origin,后端在接受到请求后确定响应后会在Response Headers中加入一个属性:Access-Control-Allow-Origin,值就是发起请求的源地址(http://127.0.0.1:8888),浏览器得到响应会进行判断Access-Control-Allow-Origin的值是否和当前的地址相同,只有匹配成功后才进行响应处理。

    现代浏览器中和移动端都支持CORS(除了opera mini),IE下需要8+

    前端:

    //http://127.0.0.1:8888/cors.html
    var xhr = new XMLHttpRequest();
    xhr.onload = function(data){
      var _data = JSON.parse(data.target.responseText)
      for(key in _data){
        console.log('key: ' + key +' value: ' + _data[key]);
      }
    };
    xhr.open('POST','http://127.0.0.1:2333/cors',true);
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    xhr.send();

    后端:

    //http://127.0.0.1:2333/cors
    app.post('/cors',(req,res) => {
      if(req.headers.origin){
        res.writeHead(200,{
          "Content-Type": "text/html; charset=UTF-8",
          "Access-Control-Allow-Origin":'http://127.0.0.1:8888'
        });
        let people = {
          type : 'cors',
          name : 'weapon-x'
        }
        res.end(JSON.stringify(people));
      }
    })

    可以在开发者工具里面看到请求的详细信息,并且在控制台也可以看到返回的数据输出:


    response header.png

    cors console.png

    3、服务器跨域

    在前后端分离的项目中可以借助服务器实现跨域,具体做法是:前端向本地服务器发送请求,本地服务器代替前端再向api服务器接口发送请求进行服务器间通信,本地服务器其实就是个中转站的角色,再将响应的数据返回给前端,下面用node.js做一个示例

    前端:

    //http://127.0.0.1:8888/server
    var xhr = new XMLHttpRequest();
        xhr.onload = function(data){
          var _data = JSON.parse(data.target.responseText)
          for(key in _data){
            console.log('key: ' + key +' value: ' + _data[key]);
          }
        };
        xhr.open('POST','http://127.0.0.1:8888/feXhr',true);  //向本地服务器发送请求   
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xhr.send("url=http://127.0.0.1:2333/beXhr");    //以参数形式告知需要请求的后端接口

    后端:

    //http://127.0.0.1:8888/feXhr
    app.post('/feXhr',(req,res) => {
      let url  = req.body.url;
      superagent.get(url)           //使用superagent想api接口发送请求
          .end(function (err,docs) {
              if(err){
                  console.log(err);
                  return
              }
              res.end(docs.res.text); //返回到前端
          })
    })
    
    //http://127.0.0.1:2333/beXhr
    app.get('/beXhr',(req,res) => {
      let obj = {
        type : 'superagent',
        name : 'weapon-x'
      };
      res.writeHead(200, {"Content-Type": "text/javascript"});
      res.end(JSON.stringify(obj));     //响应
    })

    回到 http://127.0.0.1:8888/server 页面打开控制台可以看到数据输出:

    五、处理跨域的方法3 -- XHR2

    “XHR2” 全称 “XMLHttpRequest Level2” 是HTML5提供的方法,对跨域访问提供了很好的支持,并且还有一些新的功能。

    * IE10以下的版本都不支持

    * 只需要在服务器端头部加上下面两句代码:

    header( "Access-Control-Allow-Origin:*" );

    header( "Access-Control-Allow-Methods:POST,GET" );



  • 相关阅读:
    软件项目技术点(7)——在canvas上绘制自定义图形
    软件项目技术点(4)——实现点击选中画布上元素
    软件项目技术点(5)——在canvas上绘制动态网格线
    软件项目技术点(3)——多画布职责分离
    软件项目技术点(1)——游戏主循环机制
    Node.js Express 框架
    nodejs进阶(7)—async异步流程控制
    利用shell脚本快速定位日志
    MySQL数据库查询所有表名
    MySQL数据库中查询表的所有列名
  • 原文地址:https://www.cnblogs.com/huangshikun/p/6640907.html
Copyright © 2020-2023  润新知