同源策略與 JSONP CORS

同源策略與 JSONP CORS

同源策略

同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,若是缺乏了同源策略,則瀏覽器的正常功能可能都會受到影響。能夠說 Web 是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。javascript

所謂同源是指,域名,協議,端口相同。若是非同源,那麼在請求數據時,瀏覽器會在控制檯中報一個異常,提示拒絕訪問。css

示例

client:http://127.0.0.1:8000html

<!-- 前端頁面 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>index</h3>

<button class="get_service">服務</button>

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

<script>
    $(".get_service").click(function () {
        $.ajax({
            url: "http://127.0.0.1:8001/service/",
            success: function (data) {
                console.log(data);
            }
        });
    });

</script>
</body>
</html>
# views.py
def index(request):
    return render(request, "index.html")

service:http://127.0.0.1:8001前端

# views.py
def service(request):
    info = {"name": "egon", "age": 34, "price": 200}
    return HttpResponse(json.dumps(info))

當在 client 上按下按鈕,會報以下錯誤 (在火狐瀏覽器中查看) :java

firefox1

此時查看 service 端,發現請求已經發生,是瀏覽器對非同源請求返回的結果作了攔截。python

JSONP

JSONP 是 JSON 用來跨域的一個東西。原理是經過 script 標籤的跨域特性來繞過同源策略。jquery

JSONP 的原型:建立一個回調函數,而後在遠程服務上調用這個函數而且將 JSON 數據形式做爲參數傳遞,完成回調。將 JSON 數據填充進回調函數,這就是 JSONP 的 JSON+Padding 的含義。git

客戶端

客戶端在 AJAX 發送數據的時候改變其 dataType 屬性的值爲 jsonp ,並增長一個屬性 jsonp: "callbacks" 便可。github

$(".get_service").click(function () {
    $.ajax({
        url: "http://127.0.0.1:8001/service/",
        type: "get",
        dataType: "jsonp",    // 僞造ajax  基於script
        jsonp: "callbacks",
        success: function (data) {
            console.log(data);
        }
    });
});

服務端

服務端的視圖函數中將所需數據以回調函數的形式返回:ajax

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

CORS

CORS 是最經常使用的方式,其方法比 JSONP 簡單,客戶端無需改動,只需在服務端加上 response["Access-Control-Allow-Origin"] 頭就行。其值賦值爲容許訪問的源,即地址和端口號,若是賦值爲 "*" ,表明全部源均可訪問。

def service(request):
    info = {"name": "egon", "age": 34, "price": 200}
    response = HttpResponse(json.dumps(info))
    response["Access-Control-Allow-Origin"] = "*"
    return response

一個 JSONP 的應用

經過一個接口獲得以 JSONP 回調函數形式的數據,對其進行整理獲得一週內天天的節目列表。

// 實例應用
    $(".get_service").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) {
                    html += '<p>'+ weekday.week +'</p>';
                    $.each(weekday.list, function (j, show) {
                        html += '<p><label>'+ show.time +'</label>&nbsp;&nbsp;<a href='+ show.link +'>'+ show.name +'</a></p>';
                    });
                });

                $("body").append(html);
            }
        });
    });

GitHub 地址:https://github.com/protea-ban/oldboy/tree/master/9day85

相關文章
相關標籤/搜索