日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【Python之路】第十七篇

 highoo 2019-03-20
概述

1、傳統(tǒng)的Web應(yīng)用

一個(gè)簡(jiǎn)單操作需要重新加載全局?jǐn)?shù)據(jù)

2、AJAX

AJAX,Asynchronous JavaScript and XML (異步的JavaScript和XML),一種創(chuàng)建交互式網(wǎng)頁(yè)應(yīng)用的網(wǎng)頁(yè)開(kāi)發(fā)技術(shù)方案。

  • 異步的JavaScript:
    使用 【JavaScript語(yǔ)言】 以及 相關(guān)【瀏覽器提供類(lèi)庫(kù)】 的功能向服務(wù)端發(fā)送請(qǐng)求,當(dāng)服務(wù)端處理完請(qǐng)求之后,【自動(dòng)執(zhí)行某個(gè)JavaScript的回調(diào)函數(shù)】。
    PS:以上請(qǐng)求和響應(yīng)的整個(gè)過(guò)程是【偷偷】進(jìn)行的,頁(yè)面上無(wú)任何感知。
  • XML
    XML是一種標(biāo)記語(yǔ)言,是Ajax在和后臺(tái)交互時(shí)傳輸數(shù)據(jù)的格式之一

利用AJAX可以做:
1、注冊(cè)時(shí),輸入用戶名自動(dòng)檢測(cè)用戶是否已經(jīng)存在。
2、登陸時(shí),提示用戶名密碼錯(cuò)誤
3、刪除數(shù)據(jù)行時(shí),將行ID發(fā)送到后臺(tái),后臺(tái)在數(shù)據(jù)庫(kù)中刪除,數(shù)據(jù)庫(kù)刪除成功后,在頁(yè)面DOM中將數(shù)據(jù)行也刪除。(博客園)

“偽”AJAX

由于HTML標(biāo)簽的iframe標(biāo)簽具有局部加載內(nèi)容的特性,所以可以使用其來(lái)偽造Ajax請(qǐng)求。

iframe.src 重新加載,頁(yè)面不刷新

復(fù)制代碼
<!DOCTYPE html>
<html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div>
            <p>請(qǐng)輸入要加載的地址:<span id="currentTime"></span></p>
            <p>
                <input id="url" type="text" />
                <input type="button" value="刷新" onclick="LoadPage();">
            </p>
        </div>
  
        <div>
            <h3>加載頁(yè)面位置:</h3>
            <iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
        </div>
  
        <script type="text/javascript">
  
            window.onload= function(){
                var myDate = new Date();
                document.getElementById('currentTime').innerText = myDate.getTime();
            };
            function LoadPage(){
                var targetUrl =  document.getElementById('url').value;
                document.getElementById("iframePosition").src = targetUrl;
            }
        </script>
    </body>
</html>
復(fù)制代碼

 

原生AJAX

Ajax主要就是使用 【XmlHttpRequest】對(duì)象來(lái)完成請(qǐng)求的操作,該對(duì)象在主流瀏覽器中均存在(除早起的IE),Ajax首次出現(xiàn)IE5.5中存在(ActiveX控件)。

1、XmlHttpRequest對(duì)象介紹

XmlHttpRequest對(duì)象的主要方法:

View Code

XmlHttpRequest對(duì)象的主要屬性:

View Code

2、跨瀏覽器支持

  • XmlHttpRequest

    IE7+, Firefox, Chrome, Opera, etc.

  • ActiveXObject("Microsoft.XMLHTTP")

    IE6, IE5

基于原生Ajax-demo

原生ajax發(fā)送post請(qǐng)求要帶上請(qǐng)求頭

1
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
jQuery Ajax

jQuery其實(shí)就是一個(gè)JavaScript的類(lèi)庫(kù),其將復(fù)雜的功能做了上層封裝,使得開(kāi)發(fā)者可以在其基礎(chǔ)上寫(xiě)更少的代碼實(shí)現(xiàn)更多的功能。

  • jQuery 不是生產(chǎn)者,而是大自然搬運(yùn)工。
  • jQuery Ajax本質(zhì) XMLHttpRequest 或 ActiveXObject 

注:2.+版本不再支持IE9以下的瀏覽器

Jquery Ajax-方法
基于JqueryAjax -demo

通過(guò)ajax返回得到的字符串,可以通過(guò)  obj = JSON.parse(callback) 轉(zhuǎn)換回原來(lái)格式!

跨域AJAX

由于瀏覽器存在同源策略機(jī)制,同源策略阻止從一個(gè)源加載的文檔或腳本獲取或設(shè)置另一個(gè)源加載的文檔的屬性。

特別的:由于同源策略是瀏覽器的限制,所以請(qǐng)求的發(fā)送和響應(yīng)是可以進(jìn)行,只不過(guò)瀏覽器不接受罷了。

瀏覽器同源策略并不是對(duì)所有的請(qǐng)求均制約:

  • 制約: XmlHttpRequest

  • 不叼: img、iframe、script等具有src屬性的標(biāo)簽  => 相當(dāng)于發(fā)送了get請(qǐng)求

跨域,跨域名訪問(wèn),如:http://www. 域名向 http://www.域名發(fā)送請(qǐng)求。

1、JSONP實(shí)現(xiàn)跨域請(qǐng)求

JSONP(JSONP - JSON with Padding是JSON的一種“使用模式”),利用script標(biāo)簽的src屬性(瀏覽器允許script標(biāo)簽跨域)

復(fù)制代碼
-- localhost:8889 :

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("func([11,22,33,44])")

*******************************************
-- localhost:8888 :

function Jsonp1(){
    var tag = document.createElement('script');
    tag.src = 'http://localhost:8889/index';
    document.head.appendChild(tag);
    document.head.removeChild(tag);
}

function func(arg) {
    console.log(arg)
}
復(fù)制代碼

Jsonp1() 被執(zhí)行后,創(chuàng)建了一個(gè)<script> 代碼塊 , 填充了返回值!

1
2
3
<script>
    func([11,22,33,44])
</script>

接著執(zhí)行了 func() 輸出 [11,22,33,44]

復(fù)制代碼
-- jQuery 實(shí)現(xiàn)方式:
function
jsonpclick() { $.ajax({ url:'http://localhost:8889/index', dataType:'jsonp', jsonpCallback:'func', }); }
復(fù)制代碼

改進(jìn)版:

復(fù)制代碼
-- localhost:8889 :

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        callback = self.get_argument('callback')
        self.write("%s([11,22,33,44])"%callback)

此時(shí)頁(yè)面中,訪問(wèn):
http://localhost:8889/index?callback=xxoo
http://localhost:8889/index?callback=ssss
都可以!
*******************************************
-- localhost:8888 :

function func(arg) {
    console.log(arg)
}

function jsonpclick() {
    $.ajax({
        url:'http://localhost:8889/index',
        dataType:'jsonp',
        jsonp:'callback',
        jsonpCallback:'func',
    });
}
復(fù)制代碼

代碼中相當(dāng)于發(fā)送了: http://localhost:8889/index?callback=func

1
2
3
4
5
6
jsonp:要求為String類(lèi)型的參數(shù),在一個(gè)jsonp請(qǐng)求中重寫(xiě)回調(diào)函數(shù)的名字。
該值用來(lái)替代在"callback=?"這種GET或POST請(qǐng)求中URL參數(shù)里的"callback"部分,
例如 {jsonp:'onJsonPLoad'} 會(huì)導(dǎo)致將"?onJsonPLoad="傳給服務(wù)器。
jsonpCallBack: 區(qū)分大小寫(xiě)
實(shí)例: 江西電視臺(tái)節(jié)目單獲取

2、CORS

隨著技術(shù)的發(fā)展,現(xiàn)在的瀏覽器可以支持主動(dòng)設(shè)置從而允許跨域請(qǐng)求,

即:跨域資源共享(CORS,Cross-Origin Resource Sharing)

其本質(zhì)是設(shè)置響應(yīng)頭,使得瀏覽器允許跨域請(qǐng)求。

* 簡(jiǎn)單請(qǐng)求 OR 非簡(jiǎn)單請(qǐng)求

1
2
3
4
5
6
7
8
9
10
11
12
13
條件:
    1、請(qǐng)求方式:HEAD、GET、POST
    2、請(qǐng)求頭信息:
        Accept
        Accept-Language
        Content-Language
        Last-Event-ID
        Content-Type 對(duì)應(yīng)的值是以下三個(gè)中的任意一個(gè)
                                application/x-www-form-urlencoded
                                multipart/form-data
                                text/plain
  
注意:同時(shí)滿足以上兩個(gè)條件時(shí),則是簡(jiǎn)單請(qǐng)求,否則為復(fù)雜請(qǐng)求

* 簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求的區(qū)別?

1
2
簡(jiǎn)單請(qǐng)求:一次請(qǐng)求
非簡(jiǎn)單請(qǐng)求:兩次請(qǐng)求,在發(fā)送數(shù)據(jù)之前會(huì)先發(fā)一次請(qǐng)求用于做“預(yù)檢”,只有“預(yù)檢”通過(guò)后才再發(fā)送一次請(qǐng)求用于數(shù)據(jù)傳輸。

* 關(guān)于“預(yù)檢”

1
2
3
4
5
6
7
- 請(qǐng)求方式:OPTIONS
- “預(yù)檢”其實(shí)做檢查,檢查如果通過(guò)則允許傳輸數(shù)據(jù),檢查不通過(guò)則不再發(fā)送真正想要發(fā)送的消息
- 如何“預(yù)檢”
     => 如果復(fù)雜請(qǐng)求是PUT等請(qǐng)求,則服務(wù)端需要設(shè)置允許某請(qǐng)求,否則“預(yù)檢”不通過(guò)
        Access-Control-Request-Method
     => 如果復(fù)雜請(qǐng)求設(shè)置了請(qǐng)求頭,則服務(wù)端需要設(shè)置允許某請(qǐng)求頭,否則“預(yù)檢”不通過(guò)
        Access-Control-Request-Headers

基于cors實(shí)現(xiàn)AJAX請(qǐng)求:

a、支持跨域,簡(jiǎn)單請(qǐng)求

1
2
3
4
5
服務(wù)器設(shè)置響應(yīng)頭:Access-Control-Allow-Origin = '域名' '*'
self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
self.set_header('Access-Control-Allow-Origin', "http://localhost:8888,http://localhost:9999")
self.set_header('Access-Control-Allow-Origin', "*")    //所有網(wǎng)站

實(shí)例:

復(fù)制代碼
function corsSimple() {
    $.ajax({
        url:'http://localhost:8889/index',
        type:'post',
        data:{'v1':'k1'},
        success:function (callback) {
            console.log(callback)
        }
    });
}

***********************************************
-- localhost:8889
def post(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    v1 = self.get_argument('v1')
    print(v1)
    self.write('--post--')
復(fù)制代碼

b、支持跨域,復(fù)雜請(qǐng)求

由于復(fù)雜請(qǐng)求時(shí),首先會(huì)發(fā)送“預(yù)檢”請(qǐng)求,如果“預(yù)檢”成功,則發(fā)送真實(shí)數(shù)據(jù)。

  • “預(yù)檢”請(qǐng)求時(shí),允許請(qǐng)求方式則需服務(wù)器設(shè)置響應(yīng)頭:Access-Control-Request-Method

  • “預(yù)檢”請(qǐng)求時(shí),允許請(qǐng)求頭則需服務(wù)器設(shè)置響應(yīng)頭:Access-Control-Request-Headers

  • “預(yù)檢”緩存時(shí)間,服務(wù)器設(shè)置響應(yīng)頭:Access-Control-Max-Age

復(fù)制代碼
--localhost:8889

def options(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Methods', "PUT")
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    print('--option--')
def put(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    print('--put--')
    self.write('--put--')

***********************************************
--localhost:8888

function corscomplex() {
    $.ajax({
        url:'http://localhost:8889/index',
        type:'put',
        data:{'v1':'k1'},
        success:function (callback) {
            console.log(callback)
        }
    });
}
復(fù)制代碼

如果客戶端,加上了自定義請(qǐng)求頭,服務(wù)器端要加上

1
self.set_header('Access-Control-Allow-Headers', "key1,key2")

實(shí)例:

復(fù)制代碼
--localhost:8889

def options(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Methods', "PUT")
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    self.set_header('Access-Control-Allow-Headers', "key1,key2")
    self.set_header('Access-Control-Max-Age', 10)
    print('--option--')
def put(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    print('--put--')
    self.write('--put--')

***********************************************
--localhost:8888

function corscomplex() {
    $.ajax({
        url:'http://localhost:8889/index',
        type:'put',
        headers:{'key1':'xxx'},
        data:{'v1':'k1'},
        success:function (callback) {
            console.log(callback)
        }
    });
}
復(fù)制代碼

控制預(yù)檢過(guò)期時(shí)間:

1
self.set_header('Access-Control-Max-Age', 10)   //10

c、跨域傳輸cookie

在跨域請(qǐng)求中,默認(rèn)情況下,HTTP Authentication信息,Cookie頭以及用戶的SSL證書(shū)無(wú)論在預(yù)檢請(qǐng)求中或是在實(shí)際請(qǐng)求都是不會(huì)被發(fā)送。

如果想要發(fā)送:

  • 瀏覽器端:XMLHttpRequest的withCredentials為true

  • 服務(wù)器端:Access-Control-Allow-Credentials為true

  • 注意:服務(wù)器端響應(yīng)的 Access-Control-Allow-Origin 不能是通配符 *

復(fù)制代碼
--localhost:8889

def options(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Methods', "PUT")
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    self.set_header('Access-Control-Allow-Credentials', "true")   //必須
    print('--option--')
def put(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    self.set_header('Access-Control-Allow-Credentials', "true")   //必須print(self.cookies)
    self.set_cookie('k1','kkk')
    self.write('--put--')

***********************************************
--localhost:8888

function corscomplex() {
    $.ajax({
        url:'http://localhost:8889/index',
        type:'put',
        data:{'v1':'k1'},
        xhrFields:{withCredentials: true},
        success:function (callback) {
            console.log(callback)
        }
    });
}    
復(fù)制代碼

d、跨域獲取響應(yīng)頭

默認(rèn)獲取到的所有響應(yīng)頭只有基本信息,如果想要獲取自定義的響應(yīng)頭,則需要再服務(wù)器端設(shè)置Access-Control-Expose-Headers。

復(fù)制代碼
--localhost:8889

def options(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Methods', "PUT")
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    self.set_header('Access-Control-Allow-Headers', "key1,key2")
    self.set_header('Access-Control-Allow-Credentials', "true")   
    print('--option--')
def put(self, *args, **kwargs):
    self.set_header('Access-Control-Allow-Origin', "http://localhost:8888")
    self.set_header('Access-Control-Allow-Credentials', "true")   
    self.set_header('bili', "daobidao")    //設(shè)置響應(yīng)頭
    self.set_header('Access-Control-Expose-Headers', "xxoo,bili")   //允許發(fā)送
    print(self.cookies)
    self.set_cookie('k1','kkk')
    self.write('--put--')

***********************************************
--localhost:8888

function corsRequest() {
    $.ajax({
        url:'http://localhost:8889/index',
        type:'put',
        data:{'v1':'k1'},
        xhrFields:{withCredentials: true},
        success:function (callback,statusText, xmlHttpRequest) {
      console.log(callback);
      console.log(xmlHttpRequest.getAllResponseHeaders());
    }
    });
}    
復(fù)制代碼

示例代碼整合:

localhost:8888/index.html
localhost:8889/python

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多