zoukankan      html  css  js  c++  java
  • 跨域问题

    跨域

    请求不同源地址

    同源策略

    同源:域名、协议、端口号相同的地址。不同源地址之间默认不能进行请求。

    通过img尝试跨域请求

    可以发送不同源地址之间的请求,但不能得到响应体。因为浏览器会将地址中的图片转化成二进制,无法通过字符串响应回来

    通过link尝试跨域请求

    可以发送不同源地址之间的请求,但不能得到响应体。因为 不能拿到link中链入文件的内容

    通过script尝试跨域请求

    可以发送不同源地址之间的请求,但不能得到响应体。因为不能拿到script中引入文件的内容,但是可以通过在引入文件中设置js编码格式,并通过调用主页面上的方法来自动输出服务器内容

     

    解决方法

    jsonp

    • 通过script标签完成不同源地址之间的跨域请求

    • 通过script标记请求一个服务端的PHP文件,而这个文件返回的是js代码,而js作用是调用事先定义好的函数,从而将服务端想要给客户端发过去的数据发送给客户端

    <script src='../jquery.js'></script>
    <script>
    //因为多次调用同一个函数会覆盖,所以随机生成函数名 //按照函数命名法则,第一位不是数字,中间不能有.
    var callback_name='ashen_'+Date.now()+Math.random().toString().substr(2,5);
    var script=document.createElement('script');
    //设置get的特定url
    script.src='http://localhost:88/day12/code/jsonp/jsonp.php?'+'callback_name='+callback_name;
    document.body.appendChild(script);
    //函数输出服务端结果 因为当请求还未完成时,无法得到res,所以定义为页面加载函数,页面执行完成才执行
    window[callback_name]=function(res){
    console.log(res);
    }
    </script>
    <?php
    //将编码方式设置为application/javascript,才能调用客户端方法输出数据
    $timenow = time();
    //如果客户端没有给出特定url即特定调用的函数,则直接输出json数据
    if (empty($_GET['callback_name'])) {
    header('Content-Type:application/json');
    echo json_encode($timenow);
    exit();
    }
    header('Content-Type:application/javascript');
    //否则将json数据反序列化赋值给result
    $result = json_encode($timenow);
    //获取传入的函数名,赋值给$callback_name
    $callback_name = $_GET['callback_name'];
    //如果$callback_name类型是函数,则输出结果
    echo "typeof {$callback_name}==='function' && {$callback_name}({$result})";
    17.5.1 封装jsonp,服务端代码如上
    function jsonp(url,params,callback){
    //获取随机函数名
    var callback_name='jsonp_'+Date.now()+Math.random().toString().substr(2,5);

    //判断params即传入数据类型 当为对象时......
    if (typeof params === 'object') {
           var tempArr = [];
           for (var key in params) {
             var value = params[key];
             tempArr.push(key + '=' + value);
          }
           params = tempArr.join('&');
        }

           //创建script
    var script=document.createElement('script');
    //设置src 将url 传入的数据 函数名传入 callback是get方法传输的一个键
    script.src=url+'?'+params+'&callback='+callback_name;
    document.body.appendChild(script);
    //向页面加载函数中添加名为callback_name的函数,并在其中调用此函数
    window[callback_name] = function (data) {
           callback(data)

           //执行完后,删除页面加载中的此函数 删除页面中的此script
           delete window[callback_name]
           document.body.removeChild(script)
        }
    }

    jsonp('http://localhost:88/day12/code/jsonp/jsonp.php',{id:123},function(res){
    console.log(res);
    })

    17.6 跨域资源共享(cors)

    设置被访问页面的Access-Control-Allow-Origin为* 允许任何页面访问,Access-Control-Allow-Origin为特定url,允许该页面访问

    proxy请求转发代理

    在vue或react项目中,可以直接通过原本提供的proxy转发跨域请求。通过设置proxy,可以实现转跨域请求为同域请求

  • 相关阅读:
    Nginx出现413 Request Entity Too Large错误解决方法
    Apache设置二级域名和虚拟主机
    LNMP搭建03 -- 编译安装PHP
    LNMP搭建04 -- 配置Nginx支持PHP
    LNMP搭建01 -- 编译安装MySQL 5.6.14 和 LNMP相关的区别
    LNMP搭建02 -- 编译安装Nginx
    vagrant使用小结
    LeetCode Count and Say
    基于ArcGIS Flex API实现动态标绘(1.0)
    HDU 2027 汉字统计
  • 原文地址:https://www.cnblogs.com/ashen1999/p/12559686.html
Copyright © 2011-2022 走看看