Ajax之跨域請求


Ajax之跨域請求

 

  一、引子

  我現在開啟了兩個django項目,分別叫Demo1和Demo2,Demo1中有一個路徑‘http://127.0.0.1:8000/index/’,對應的視圖是index視圖返回一個index頁面,頁面中只有一個button按鈕,按鈕綁定了一個單擊事件,點擊之后會發送一個ajax請求,請求的路徑為‘http://127.0.0.1:8001/ajax/’,Demo1的ip和端口號是:‘http://127.0.0.1:8000/’,Demo2的ip和端口號是:‘http://127.0.0.1:8001/’。前面一段描述就是在Demo1項目的一個頁面向Demo2項目發送一個ajax請求,在Demo2有對應的路徑和視圖來處理請求,並返回值。我們運行一下。報錯如下:

  這就是一個已攔截的跨域請求的錯誤,錯誤內容是CORS頭少“Access-Control-Allow-Origin”。這就是我們用ajax發送一個跨域請求出現的錯誤,這就是今天我要處理的一個問題。

  二、同源策略

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

同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支持JavaScript的瀏覽器都會用這個策略。所謂的同源,即指:域名、端口、協議同時相同。比如說你用ajax發請求時,會檢查你發送的請求是否發送路徑是否ajax所在的JavaScript屬於同源,即是兩者的ip、端口、協議相同。如果不是同源,瀏覽器就會報錯,提示拒絕訪問。

  想要實現用ajax發送跨域請求有兩種方式,一是jsonp,而是cors。

  三、基於JSONP的ajax跨域請求

  1,版本1

  我們在用script引入js代碼,有時用的是網上路徑,意思就是在我們的項目去請求其他項目的,如:

  這種情況下是可以請求成功的,於是,我們可以運用這一功能,給button按鈕綁定事件,事件的功能是創建一個script標簽,然后添加到頁面上,這樣當我們點擊button按鈕就會發送一個跨域請求,而且還是允許的。

  Demo1項目index.html頁面上添加js代碼:

function get_ele_script(url){
            var ele_script=$('<script>');
            ele_script.attr('src',url);
            ele_script.attr('id','ele_script');
            $('body').append(ele_script);
            $('#ele_script').remove()
        }
 $('.cli').click(function () {
            get_ele_script('http://127.0.0.1:8001/ajax/')
        })

  這樣就成功用點擊事件發送了一個跨域請求,在Demo2的視圖中,有返回值,但如果我不定義返回的值,HTML文件就會報沒有定義的錯誤,而且視圖返回的值在前端頁面是以變量的形式顯示。

  Demo2項目的視圖:

def ajax(request):
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    return HttpResponse('f(%s)'%dic_json)

  此時,我們就應該在HTML文件中定義f()

function f(params) {
            console.log(params);
            console.log(typeof params);
        }

  這樣,當我們點擊button時,會往Demo2發送一個請求,Demo2會返回帶參數的f(),由於已經定義了f()函數,所以當返回時會執行這個函數,這種方法就實現了發送跨域請求,然后接受返回值,並對返回值進行處理。

  2,版本2

  其實版本1在Demo2項目中把返回的函數名寫死了,如果照版本1,所有來反問Demo2的瀏覽器都會得到一個叫f()的函數,我們在聲明的時候也只能寫成f()。其實我們可以這樣在請求的時候把我們定義的函數名一起發過去,讓他就給我返回我發送過去的函數,這樣,我們定義函數名就可以隨意了。

  Demo1項目的index.html頁面上就應這樣寫:

function f(params) {
            console.log(params);
            console.log(typeof params);
        }
$('.cli').click(function () {
            get_ele_script('http://127.0.0.1:8001/ajax/?callbacks=f')

  Demo2項目的視圖:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    return HttpResponse('%s(%s)'%(a,dic_json))

  3,版本3

  上面兩個版本就沒有基於ajax請求,這個版本就基於ajax發送跨域請求。

  Demo1項目下的index.html頁面上:

function f(params) {
            console.log(params);
            console.log(typeof params);
        }
$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/callbacks=f',
                type:'GET',
                dataType:'jsonp',
            })
        })

  Demo2項目的視圖:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    print(type(dic_json))
    return HttpResponse('%s(%s)'%(a,dic_json))

  4,版本4

  這也是基於ajax發送的跨域請求,只是比上一版本更簡單。

  Demo1項目下的index.html:

function f(params) {
            console.log(params);
            console.log(typeof params);
        }
$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/',
                type:'GET',
                dataType:'jsonp',
                jsonp:'callbacks',
                jsonpCallback:'f'
            })
        })

  Demo2項目的視圖:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    print(type(dic_json))
    return HttpResponse('%s(%s)'%(a,dic_json))

  5,版本5(終極版本)

  基於ajax的跨域請求,並把返回值給ajax的success。

  Demo1項目下的index.html:

$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/',
                type:'GET',
                dataType:'jsonp',
                jsonp:'callbacks',
                success:function (data) {
                    console.log(data)
                }
            })
        })

  Demo2項目下的視圖:

def ajax(request):
    a=request.GET.get('callbacks')
    dic={'name':'zhnag','age':46}
    dic_json=json.dumps(dic)
    return HttpResponse('%s(%s)'%(a,dic_json))

  這個版本就比較簡單,書寫方便

  四、基於CORS的ajax跨域請求

  最開始,我們講的報錯是:CORS頭少:‘Access-Control-Allow-Origin’,既然少一個,我們就加一個,就可以了,其實這種方式才是最常用。

  Demo1項目下的index.html:

$('.cli').click(function () {
            $.ajax({
                url:'http://127.0.0.1:8001/ajax/',
                type:'get',
                data:{'a':1},
                success:function (res) {
                    console.log(res)
                }
            })
        })

  Demo2項目下的視圖:

def ajax(request):
    dic = {'name': 'zhnag', 'age': 46}
    http=HttpResponse(json.dumps(dic))
    http['Access-Control-Allow-Origin']='http://127.0.0.1:8000'     #這相當於加了一個白名單,對於‘http://127.0.01:8000’的跨域請求就允許通行
    return http

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM