跨域问题

跨域

请求不同源地址

同源策略

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

通过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,可以实现转跨域请求为同域请求

posted @ 2020-03-24 16:19  ashen1999  阅读(289)  评论(0编辑  收藏  举报