跨域
同源策略
同源:域名、协议、端口号相同的地址。不同源地址之间默认不能进行请求。
通过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,允许该页面访问
来源:https://www.cnblogs.com/ashen1999/p/12559686.html