• ajax跨域、jsonp原理


    Ajax跨域

    • 同源策略

      • 同源策略是浏览器的一种安全策略,所谓同源指的是请求URL地址中的协议、域名和端口都相同,只要其中之一不相同就是跨域。

      • 同源策略主要为了保证浏览器的安全性。

      • 在同源策略下,浏览器不允许Ajax跨域获取服务器数据。

    http://www.example.com/detail.html

    说明
    http://api.example.com/detail.html 域名不同
    https://www.example.com/detail.html 协议不同
    http://www.example.com:8080/detail.html 端口不同
    http://api.example.com:8080/detail.html 域名、端口不同
    https://api.example.com/detail.html 协议、域名不同
    https://www.example.com:8080/detail.html 端口、协议不同

    跨域解决方案

    • jsonp (仅仅是get请求方式)

    • document.domain+iframe

    • location.hash + iframe

    • window.name + iframe

    • window.postMessage

    • flash等第三方插件

    jsonp 原理

    • 静态script标签的src属性进行跨域请求

      <script src="http://www.ajaxDemo.cc/check.php"></script> <!-- 同步加载 -->
      <!--<script src="http://www.ajaxDemo.cc/check.php" async></script>--> <!-- async 异步加载 -->
      <script >
          /*
              这种方式存在的两个主要的问题:
              1、必须保证加载的顺序
              2、不方便通过程序传递参数
              */
          console.log(data)
      </script>
      
      
    • 动态创建script标签,通过标签的src属性发送请求(异步请求)

      <script>
          var script = document.createElement('script');
          script.src = 'http://www.ajaxDemo.cc/check.php?callback=foo';
      
          var head = document.getElementsByTagName('head')[0];
          head.appendChild(script);
      		
          function foo(data){
              console.log(data)
          }
      </script>
      
      // check.php
      $cb = $_GET['callback'];
      $data = '{"code":"2","msg":"登录失败"}';
      echo "$cb($data)";
      

    原理:

    动态创建script标签,然后通过它的src属性发送跨域请求,然后服务器端响应的数据格式为【函数调用(foo(实参))】,所以在发送请求之前必须先声明一个函数(foo),并且函数的名字与参数中传递的名字要一致。这里声明的函数是由服务器响应的内容(实际就是一段js代码-函数调用)来调用。

    • 需要注意的是,callback参数定义是需要前后端定义好的,具体什么名字,商讨好就可以了

    jQuery 对 jsonp 的支持

    $.ajax({
        url: 'http://www.ajaxDemo.cc/check.php',
        type:'get',
        dataType: 'jsonp', //指定服务器返回的数据类型
        jsonp:'cb', //指定参数名称,默认是callback
        jsonpCallback:'abc', //指定回调函数名称,默认是 "jQuery" + ( version + Math.random() ).replace( /D/g, "" )+当前时间毫秒数
        data:{},
        success: function(res){
            console.log(res)
        },
        error:function(err){
            console.log(err)
        }
    })
    

    jsonp 接口

    • 基于jsonp的常见功能

      • 搜索智能提示

      • 快递查询

    • 第三方接口介绍(json/jsonp)

    模拟 jQuery jsonp封装可跨域请求

    function ajax(obj){
        var defaults = {
            type : 'get',
            async : true,
            url : '#',
            dataType : 'text',
            jsonp : 'callback',
            data : {},
            success:function(data){console.log(data);}
        }
    
        for(var key in obj){
            defaults[key] = obj[key];
        }
    
        if(defaults.dataType == 'jsonp'){
            ajax4Jsonp(defaults);
        }else{
            ajax4Json(defaults);
        }
    }
    
    function ajax4Json(defaults){
        // 1、创建XMLHttpRequest对象
        var xhr = null;
        if(window.XMLHttpRequest){
            xhr = new XMLHttpRequest();
        }else{
            xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }
        // 把对象形式的参数转化为字符串形式的参数
        /*
        {username:'zhangsan','password':123}
        转换为
        username=zhangsan&password=123
        */
        var param = '';
        for(var attr in defaults.data){
            param += attr + '=' + defaults.data[attr] + '&';
        }
        if(param){
            param = param.substring(0,param.length - 1);
        }
        // 处理get请求参数并且处理中文乱码问题
        if(defaults.type == 'get'){
            defaults.url += '?' + encodeURI(param);
        }
        // 2、准备发送(设置发送的参数)
        xhr.open(defaults.type,defaults.url,defaults.async);
        // 处理post请求参数并且设置请求头信息(必须设置)
        var data = null;
        if(defaults.type == 'post'){
            data = param;
            xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        }
        // 3、执行发送动作
        xhr.send(data);
        // 处理同步请求,不会调用回调函数
        if(!defaults.async){
            if(defaults.dataType == 'json'){
                return JSON.parse(xhr.responseText);
            }else{
                return xhr.responseText;
            }
        }
        // 4、指定回调函数(处理服务器响应数据)
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                if(xhr.status == 200){
                    var data = xhr.responseText;
                    if(defaults.dataType == 'json'){
                        // data = eval("("+ data +")");
                        data = JSON.parse(data);
                    }
                    defaults.success(data);
                }
            }
        }
    }
    function ajax4Jsonp(defaults){
        // 这里是默认的回调函数名称
        // expando: "jQuery" + ( version + Math.random() ).replace( /D/g, "" ),
        var cbName = 'jQuery' + ('1.11.1' + Math.random()).replace(/D/g,"") + '_' + (new Date().getTime());
        if(defaults.jsonpCallback){
            cbName = defaults.jsonpCallback;
        }
    
        // 这里就是回调函数,调用方式:服务器响应内容来调用
        // 向window对象中添加了一个方法,方法名称是变量cbName的值
        window[cbName] = function(data){
            defaults.success(data);//这里success的data是实参
        }
    
        var param = '';
        for(var attr in defaults.data){
            param += attr + '=' + defaults.data[attr] + '&';
        }
        if(param){
            param = param.substring(0,param.length-1);
            param = '&' + param;
        }
        var script = document.createElement('script');
        script.src = defaults.url + '?' + defaults.jsonp + '=' + cbName + param;
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(script);
    }
    

    基本使用:

    ajax({
        url:'',
        type:'get',
        data:{},
        dataType:'jsonp'
        success: function(res){
        	console.log(res)
    	}
    })
    
  • 相关阅读:
    [Leetcode] ZigZag Conversion
    [Leetcode] Wildcard Matching
    [Leetcode] 4Sum
    [Leetcode] Word Break II
    [Leetcode] Best Time to Buy and Sell Stock III
    [Leetcode] Permutation Sequence
    [Leetcode] Surrounded Regions
    [Jobdu] 题目1522:包含min函数的栈
    CUDA2.1-原理之索引与warp
    opencv8-GPU之相似性计算
  • 原文地址:https://www.cnblogs.com/vicky123/p/13490838.html
Copyright © 2020-2023  润新知