从前端和后端分析跨域(两种方法jsonp和cors)

  • 为什么会产生跨域?

          跨域是因为浏览器的安全策略:同源策略。服务器是没有做限制的

          请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同

 如下图

  • jsonp方式

原理:有三个标签是不限制同源的分别是<script type="text/javascript" src=""资源地址></script>、type="text/css" rel="stylesheet" href="资源地址"、<img src="资源地址" alt=""/> 。当链接的资源到达浏览器时,浏览器会根据他们的类型来采取不同的处理方式,比如,如果是css文件,则会进行对页面 repaint,如果是img 则会将图片渲染出来,如果是script 脚本,则会进行执行。jsonp方式就是利用了资源到达浏览器会被执行的特性,来达到跨域的目的的。

请看下边的例子

下面是原生js

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="keywords" content="jsonp">
    <meta name="description" content="jsonp">
    <title>jsonp</title>
</head>
<body>

<script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    var url = "http://shangcheng.com/test";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script);
    function callbackFun(data)
    {
        console.log(data.age);
        console.log(data.name);
    }
</script>
</body>
</html>

服务端(以php为例)

header('Content-type:application/json'); //注意一定要设置数据类型为json 不然js解析失败
$json = ['age'=>100,'name'=>'yuanfang'];
return 'callbackFun'.'('.json_encode($json).')';  //这里的callbackFun要与前端回调执行函数一致

因为我用的是laravel框架所以附上laravel demo 

$json = ['age'=>100,'name'=>'yuanfang'];
$data = 'callbackFun'.'('.json_encode($json).')';
return response($data,200)->header('Content-type','application/json');

下面是以jq为例演示

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="keywords" content="jsonp">
    <meta name="description" content="jsonp">
    <title>ajax</title>
    <style type="text/css">
        *{margin:0;padding:0;}
        div{width:600px;height:100px;margin:20px auto;}
    </style>
</head>
<body>
<div>
    <a href="javascript:;">ajax测试</a>
</div>

<script type="text/javascript" src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    function callbackFun(data)
    {
        console.log(111);
        console.log(data.name);
        data.age = 10000000;
        alert(0000);
    }
    $(function(){
        $("a").on("click", function(){
            $.ajax({
                type:"post",
                url:"http://shangcheng.com/test",
                dataType:'jsonp',
                jsonp:'mycallback',
                jsonpCallback:'callbackFun',
                success:function(data) {
                    console.log(2222);
                    console.log(data.age);
                }
            });
        })
    });
</script>
</body>
</html>

图片上可以看到ajax回调函数callbackFun和success都被执行了,并且是先执行callbackFun,下边看另外一个例子

可以看到当我们在callbackFun中对返回值做了修改的话success中值会显示变化后的值,并且执行到alert的时候如果我们不点确定,后边success并不会执行,这说明ajax回调是同步执行的。

另外说点其他的,因为jsonp跨域是依赖于<script>所以它一定是get方式,尽管上边jqz中type写的是post但是jq底层会忽略前置设置为get

  • cors方式

nginx设置方法,假如你整个项目都需要跨域那么这种方式是比较适合的,在server中设置

    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' ;
    add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
    add_header 'Access-Control-Allow-Credentials' 'true'   //这个是设置是否接受cookie

 

laravel设置方法,可以写一个路由中间件来做验证

<?php

namespace App\Http\Middleware;

use Closure;

class CrossHttp
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        //$response->header('Access-Control-Allow-Origin', '*');
        //$response->header('Access-Control-Allow-Headers', 'Origin, Content-Type, Cookie, Accept');
        //$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
        // $response->header('Access-Control-Allow-Credentials', 'true');
        return $response;
    }
}

 

并且在kernel中注册这个中间件即可

总结jsonp和cors两种优缺点

1)jsonp只可以是get方式,cors可以使get也可以是post

2)cors兼容性不是特别好,低版本的IE不支持

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值