同源策略jsonp和cors

同源策略:

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
项目1
=================http://127.0.0.1:8001项目的index============
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>

<button>ajax</button>
{% csrf_token %}

<script>
    $("button").click(function(){
        $.ajax({
            url:"http://127.0.0.1:8002/SendAjax/",
            type:"POST",
            data:{"username":"man","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
            success:function(data){
                alert(123);
                alert(data);
            }
        })
    })
</script>
</body>
</html>

项目2

==================http://127.0.0.1:8002项目的index================
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>

<button>sendAjax</button>
{% csrf_token %}

<script>
    $("button").click(function(){
        $.ajax({
            url:"/SendAjax/",
            type:"POST",
            data:{"username":"man","csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()},
            success:function(data){
                alert(data)
            }
        })
    })
</script>

</body>
</html>


===================http://127.0.0.1:8002项目的views====================

def index(request):
    return render(request,"index.html")
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def SendAjax(request):    # 不校验csrf_token
    import json
    return HttpResponse(json.dumps("hello2"))

  

当点击项目1的按钮时,发送了请求,但是会发现报错如下:

已拦截跨源请求:同源策略禁止读取位于 http://127.0.0.1:8002/SendAjax/ 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')

如何解决同源策略实现跨域请求

使用script标签来完成跨域请求  原理是通过script标签的跨域特性来绕过同源策略。

# =============================http://127.0.0.1:8001/index

<button>ajax</button>
{% csrf_token %}

<script>
    function func(name){
        alert(name)
    }
</script>

<script src="http://127.0.0.1:8002/SendAjax/"></script>


# =============================http://127.0.0.1:8002/
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt


def SendAjax(request):
    import json
    # dic={"k1":"v1"}
    return HttpResponse("func('param')")  # return HttpResponse("func('%s')"%json.dumps(dic))

 

使用jsonp来实现跨域请求

================http://127.0.0.1:8001/index===

<button class="get_index" onclick=f()>洗剪吹</button>
<srcipt>
function ret(arg) {
  console.log(arg)
}
$(".get_index").click(function () {
             $.ajax({
                 url:"http://127.0.0.1:8002/index/",
                 type:"get",
                 dataType:"jsonp",     // 伪造ajax  基于script
                 jsonp: 'callbacks',
                 //jsonpCallback:"ret",
                 success:function (data) {
                     console.log(data)
                 }
             })
         })
</srcipt>


=================127.0.0.1:8002/index====

def index(request):  # jsonp

    func=request.GET.get("callbacks")
    # print("func",func)
    info={"name":"man","age":34,"price":200}
    return HttpResponse(" ('%s')"%(func,json.dumps(info)

 

jsonp: 'callbacks'就是定义一个存放回调函数的键,jsonpCallback是前端定义好的回调函数方法名'ret',server端接受callback键对应值后就可以在其中填充数据打包返回了; 

jsonpCallback参数可以不定义,jquery会自动定义一个随机名发过去,那前端就得用回调函数来处理对应数据了。利用jQuery可以很方便的实现JSONP来进行跨域访问。

jsonp应用

$(".get_index").click(function () {
         $.ajax({
             url:"http://www.jxntv.cn/data/jmd-jxtv2.html",
             type:"get",
             dataType:"jsonp",     // 伪造ajax  基于script
             jsonp: 'callbacks',
             jsonpCallback:"list",
             success:function (data) {
                 //console.log(data.data);
                 var html="";
                 $.each(data.data,function (index,weekday) {
                 console.log(weekday);     // {week: "周一", list: Array(19)}
                 html+='<p>'+weekday.week+'</p>';
                 $.each(weekday.list,function (j,show) {
                        html+= '<p><a href='+show.link+'>'+show.name+'</a></p>'
                     })
                 });
                 $("body").append(html)
             }
         })
        })

 

使用cors来实现跨域请求

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

============127.0.0.1:8001=====
    $(".get_service").click(function () {
             $.ajax({
             url:"http://127.0.0.1:8008/service/",
             success:function (data) {
                 console.log(data)
             }
         })
        })

==============127.0.0.1:8002======
    def service(request):
        info = {"k1":"v1","k2":"v2"}
        responce = HttpResponce(json.dumps(info))
        responce["Access-Control-Allow-Origin"] = "http://127.0.0.1:8001"
        responce["Access-Control-Allow-Origin"] = "*"      #表示所有访问通过
        return responce    

 

 

 

 

 

posted @ 2019-03-26 22:30  KIV  阅读(129)  评论(0编辑  收藏  举报