跨域AJAX

因爲瀏覽器存在同源策略,同源策略指:瀏覽器 對不一樣源的腳本或文本的訪問方式 進行的限制。好比源a的js不能讀取或設置引入的源b的元素屬性。html

(阻止從一個源 加載文檔 或腳本獲取 或設置  另外一個源 加載的文檔的屬性)。python

 

定義同源:就是指兩個頁面具備相同的協議,主機(也常說域名),端口,三個要素缺一不可。jquery

 

 

因爲同源策略是瀏覽器的限制,因此請求的發送和響應是 能夠進行,只不過瀏覽器不接受而已。ajax

 

瀏覽器的同源策略並非對全部的請求都制約:json

  制約:XmlHttpRequest跨域

  容許:img,script 等具備 src屬性的標籤瀏覽器

跨域名訪問,如: http://www.c1.com域名 向 http://www.c2.com域名發送請求。服務器

 

1.JSONP實現跨域請求app

JSONP(JSONP - JSONP with Padding 是JSON的一種 ‘使用模式’),利用script標籤的src屬性(瀏覽器容許script標籤跨域)cors

 

遠程:

views.py

def get_data(request):
    import time
    time.sleep(3)
    func_name = request.GET.get('callback')
    return HttpResponse('%s("機密數據123")'%func_name)
View Code

 

本地:

views.py

def index(request):

    return render(request,'index.html')
View Code

 

index.html

<body>

    <h1>江山如此多嬌</h1>
    <div id="i1"></div>

     <input type="button" onclick="jsonp('http://127.0.0.1:8001/get_data.html?callback=funcvv')"  value="發送JSONP請求"/>
    <input type="button" onclick="Jsonp2()" value="發送JSONP2請求">
    <input type="button" onclick="Jsonp3()" value="發送JSONP3請求">

    <script src="/static/jquery-3.2.1.js"></script>
    <script>


        /*
        手動實現jsonp
         */

        function funcvv(arg) {

            alert(arg);

        }
        function jsonp(url) {
            tag = document.createElement('script');
            tag.src = url;
            document.head.appendChild(tag);
        }



        function Jsonp2() {
            $.ajax({
                url:'http://127.0.0.1:8001/get_data.html',
                type:'GET',
                dataType:'JSONP',
                success:function (data) {
                    console.log(data);
                }

            })
        }



        function list(arg) {
            console.log(arg);
        }
         function Jsonp3(){
            $.ajax({
                url: "http://127.0.0.1:8001/get_data.html",
                type: 'GET',
                dataType: 'JSONP',
                jsonp: 'callback',
                jsonpCallback: 'list'
            })
        }
    </script>

</body>
View Code

 

筆記:

- JSONP:
        本地:先定義函數
        遠程:func("數據")
        
        方式一:手動
                /*
                function funcvvvvvv(arg) {
                    alert(arg);

                    document.head.removeChild(tag);
                }

                function jsonp(url){
                    tag = document.createElement('script');
                    tag.src = url;
                    document.head.appendChild(tag);
                }*/
        方式二:調用jQuery
                function Jsonp2(){
                    $.ajax({
                        url: "http://127.0.0.1:8000/get_data.html",
                        type: 'GET',
                        dataType: 'JSONP',
                        success: function(data){
                            console.log(data);
                        }
                    })
                }
        本質:建立script標籤    

        編寫跨域請求:
            本地:
                
                function list666(arg){
                
                }
                
                $.ajax({
                    url: "http://www.jxntv.cn/data/jmd-jxtv2.html",
                    type: 'GET',
                    dataType: 'JSONP',
                    jsonp: 'callback',
                    jsonpCallback: 'list666'
                })
                
            遠程:
                func_name = request.GET.get('callback')
                return HttpResponse('%s("機密數據")' %func_name)
View Code

 

2.CORS

如今瀏覽器能夠支持主動設置從而容許跨域請求,即:跨域資源共享(CORS,Cross-Origin Resource Sharing),其本質是設置響應頭,是的瀏覽器容許跨域請求。

 

 解決方法:

-------遠程
def cors_data(request):

    response = HttpResponse('機密數據333')
    # response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000' #設置某個能訪問的域名
    response['Access-Control-Allow-Origin'] = '*'    #全部

    return response



--------本地
views.py

def index_cors(request):
    return render(request,'index_cors.html')



.HTML
<body>

     <h1>大浪淘沙</h1>
     <script src="/static/jquery-3.2.1.js"></script>

     <script>

         $.ajax({
             url:'http://127.0.0.1:8001/cors_data.html',
             type:'GET',
             success:function (data) {
                 console.log(data);
             }
         })
     </script>
</body>
GET方式

 

 

 從而引出:

*簡單請求 OR 非簡單請求

條件:
    一、請求方式:HEAD、GET、POST
    二、請求頭信息:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type 對應的值是如下三個中的任意一個
                                application/x-www-form-urlencoded
                                multipart/form-data
                                text/plain
 
注意:同時知足以上兩個條件時,則是簡單請求,不然爲複雜請求





*簡單請求和非簡單請求的區別?
    
簡單請求:一次請求
非簡單請求:兩次請求,在發送數據以前會先發一次請求用於作「預檢」,只有「預檢」經過後纔再發送一次請求用於數據傳輸。




* 關於「預檢」

- 請求方式:OPTIONS
- 「預檢」其實作檢查,檢查若是經過則容許傳輸數據,檢查不經過則再也不發送真正想要發送的消息
- 如何「預檢」
     => 若是複雜請求是PUT等請求,則服務端須要設置容許某請求,不然「預檢」不經過
        Access-Control-Request-Method
     => 若是複雜請求設置了請求頭,則服務端須要設置容許某請求頭,不然「預檢」不經過
        Access-Control-Request-Headers

 

PUT方法請求(非簡單):

----遠程

def cors_data(request):

    if request.method == 'OPTIONS':
        #預檢
        response = HttpResponse() #可爲空
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'PUT'
        return response

    elif request.method == 'PUT':
        response = HttpResponse('機密數據333')
        # response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000' #設置某個能訪問的域名
        response['Access-Control-Allow-Origin'] = '*'    #全部

        return response




-------本地

def index_cors(request):
    return render(request,'index_cors.html')



<body>

     <h1>大浪淘沙</h1>
     <script src="/static/jquery-3.2.1.js"></script>

     <script>

         $.ajax({
             url:'http://127.0.0.1:8001/cors_data.html',
             type:'PUT',  #------PUT------
             success:function (data) {
                 console.log(data);
             }
         })
     </script>
PUT

 

 

 GET + 自定義headers(非簡單):

--------遠程

def cors_data(request):

    if request.method == 'OPTIONS':
        #預檢
        response = HttpResponse() #可爲空
        response['Access-Control-Allow-Origin'] = '*'
        # response['Access-Control-Allow-Methods'] = 'PUT'
        response['Access-Control-Allow-Headers'] = 'xxx'    # 自定義的 headers:{'xxx':333},
        return response

    elif request.method == 'GET':
        response = HttpResponse('機密數據333')
        # response['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000' #設置某個能訪問的域名
        response['Access-Control-Allow-Origin'] = '*'    #全部

        return response





-------本地
def index_cors(request):
    return render(request,'index_cors.html')


.HTML
<body>

     <h1>大浪淘沙</h1>
     <script src="/static/jquery-3.2.1.js"></script>

     <script>

         $.ajax({
             url:'http://127.0.0.1:8001/cors_data.html',
             type:'GET',
             headers:{'xxx':333},
             success:function (data) {
                 console.log(data);
             }
         })
     </script>
</body>
View Code

 

#補充:

  JSONP:具備兼容性

  CORS(早期有些瀏覽器版本,不支持)

 

  不到不得已,才讓發 非簡單請求(會增長服務器壓力)

 

例如:

 

 

 筆記:

本地:無做爲
            遠程:設置響應頭
                    response['Access-Control-Allow-Origin'] = "http://127.0.0.1:8888"
                    response['Access-Control-Allow-Methods'] = "PUT"
                    response['Access-Control-Allow-Headers'] = "xxx"
                          
View Code
相關文章
相關標籤/搜索