腳本化HTTP 取得響應 指定請求

腳本化HTTP
下面將會用js代碼操縱HTTP
下面將會說明在沒有致使web瀏覽器從新加載任何窗口或者窗體的狀況下,腳本實現web瀏覽器和服務器之間的通訊。
ajax:爲一種找早起避免頁面重載而動態更新頁面的方式,不過如今是直接數據驅動,或者相似於vue的單頁應用
comet:這個和ajax正好相反,爲推送消息到web瀏覽器端php

ps;ajax和comet都爲一個美國的洗滌日用品牌,╮(╯▽╰)╭html

總說

網頁信標

img元素有一個src屬性,當腳本設置img元素的src屬性,且把信息做爲圖片的url的查詢字符串部分,即能把通過編碼的信息椽筆給web服務器,web服務器實際上必須返回一個圖片做爲結果。
事實上,使用一個空的js腳本也可完成此操做
一個百度統計的js腳本以下vue

(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?d2539dae35b4dcf0e7814c110ecefa9f";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();

分析,一個採用es5編寫的一個閉包,動態加載一個script標籤,向https://hm.baidu.com/hm.js?d2539dae35b4dcf0e7814c110ece發送一個get請求,而且查詢的字符串爲?後面的參數,服務器只須要統計?後面的get請求數目,便可完成一次次的統計任務。用戶的頁面停留,直接計算兩次加載的時間差便可。數據庫完成統計便可。一個最簡單的頁面統計完成。java

iframe

一個淘汰的標籤。
下面是舊的ajax方式
使用iframe完成一次ajax,腳本先把要發送給web服務器的信息編碼到url中,服務器在動態的建立一個html文檔,將其內容返回給web,在iframe中顯示,這種方式受道同源的限制。
上方的方式以及放棄。web

script

經過script元素的src屬性設置url發起http get請求,即一種基於script的ajax傳輸,服務器使用json編碼,執行腳本的時候,將其轉碼,這種的ajax同時也稱爲jsonp
即這種的跨域能夠不受到同源的限制ajax

ajax中的x

ajax中的x爲xml爲一種可選的通訊方式,也可使用JSON完成通訊。chrome

其餘

一些更多的通訊協議,包括rpc(遠程過程調用)容許運行於一臺計算機的程序調用另外一臺計算機程序的子程序。若是面向對象編程,則遠程過程調用爲遠程調用,遠程方法調用。數據庫

發佈/訂閱事件系統

一種設計模式,有兩種,一種是觀察者模式,一種是發佈訂閱模式,
即,消息推送使用的是發佈/訂閱事件系統編程

觀察者模式

意圖:定義對象間的一對多的依賴關係,當一個對象狀態發生改變時,全部依賴它的對象都獲得通知,並進行更新
解決:一個對象狀態給其餘對象通知的問題,
舉例應用:有個天氣中心的目標A,專門監聽天氣的變化,而有個顯示天氣的觀察者B,B把本身註冊到A裏,當A觸發天氣變化的時候,調度B更新方法,並帶上本身的上下文。
此處輸入圖片的描述json

發佈/訂閱模式

訂閱者把本身想註冊的事件註冊到調度中心,當該事件觸發時,發佈者發佈事件到調度中心,由調度中心統一調度訂閱者註冊到調度中心的處理代碼。
舉例:有個界面實時顯示天氣,它就訂閱天氣事件(註冊到調度中心),當天氣變化時定時獲取數據,做爲發佈者到調度中心,調度中心調度訂閱者的天氣處理程序。
此處輸入圖片的描述

總結,區別

一個爲點對點,一個爲中間有一個過渡的,僅此而已。

ps 有一本書js的設計模式,推薦看看 http://shop.oreilly.com/product/0636920025832/ReviewSubmit.do?sortby=publicationDate?pageId=0636920025832.IP 以及 https://addyosmani.com/resources/essentialjsdesignpatterns/book/
購買 https://www.amazon.com/_/dp/1449331815?tag=oreilly20-20
很想知道有木有中文版的。吐槽 28美圓,合計120多元,書怎麼那麼貴呢。好貴,建議註冊一下

XMLHttpRequest

瀏覽器在CMLHttpRequest類上定義了其HTTP 的API 這個類的每一個實例都表示一個獨立請求/響應對。而且這個對象屬性和方法容許指定請求細節和提取響應數據。

同java相似,使用這個api的第一件事實例化XMLHttpRequest對象

ps:能重用已存在的XMLHttpRequest 可是以前的對象將會被掛起

HTTP請求的4個部分

  1. http請求方法或者動做
  2. 正在請求的URL
  3. 一個可選的請求頭集合,其中可能包含身份驗證信息
  4. 一個可選的請求主題

HTTP返回的響應

  1. 一個數字和文字組合成的狀態碼,如404(表示不存在)
  2. 一個響應頭集合
  3. 響應主體

爲何本地不能直接使用ajax

在本地寫js的時候,必須搭建一個服務器其AJAX才能工做
緣由:由於文件的協議爲file而本地的請求的協議爲http,因爲同源策略的影響,致使沒法使用http協議的文件,故本地沒法直接使用ajax

解決方法,chrome的瀏覽器訪問https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb 安裝chrome官方提供的本地測試服務器,用於在本地搭建服務器。
或者,編寫Node.js 使用Express框架,加載Static 模塊,完成本地的靜態服務器搭建。

指定請求

指定請求使用的是request.open(),此方法將會初始化一個請求從js代碼中調用。
第一個參數指定HTTP方法或動做,字符串不區分大小寫,一般用大寫字母匹配HTTP協議,GET用於常規請求,適用於當URL徹底指定請求資源。當請求對服務器沒有任何反作用以及當服務器的響應可緩存的時候,使用GET。對於POST來講,經常用於HTML表單,它在請求主體中包含額外數據,即表單數據,且這些數據經常儲存到服務器的數據庫中。此請求不會被緩存。
一樣的,還容許其餘的一些請求,例如DELETE,HEAD,OPTIONS,PUT等請求。
第二個參數爲URL,爲請求的主體,相對於文檔的URL,這個文檔包含調用open()的腳本,這個不能跨域,請求必須爲同域的

設置請求頭

request.setRequestHeader('Content-type', 'text/plain');

下面將會設置請求頭,上方設置請求頭爲Content-type的內容爲text/plain

有些請求頭因爲瀏覽器的安全問題,被禁止請求,因此有些不能請求。

若是請求一個受到密碼保護的url,此時不須要設置Authorization頭,只須要直接在open的第三四個參數,傳入便可。

發送請求

因爲get請求不包括主體,則直接send方法便可完成一個包的發送,

因爲跨域限制致使不能讀取

在http://1.197.156.53/編寫js以下

// 編寫請求頭GET並完成發送
var request = new XMLHttpRequest(); // 設置請求的類
request.open('GET', 'https://www.baidu.com/');  // 設置請求的連接和方式
request.setRequestHeader('Content-Type', 'text/plain'); // 設置請求頭
request.send(null); // 發送包

此處輸入圖片的描述
跨域請求被攔截。
因爲不是同源,同源被攔截

是同源的

// 編寫請求頭GET並完成發送
var request = new XMLHttpRequest(); // 設置請求的類
request.open('GET', './index.js');  // 設置請求的連接和方式
request.setRequestHeader('Content-Type', 'text/plain'); // 設置請求頭
request.send(null); // 發送包

完成一次發包操做

順序問題

HTTP請求的各個部分有指定的順序,請求方法和URL會首先到達,而後接着請求頭,最後請求主體。最後調用send()方法,完成發送。
順序問題:必須先調用open後調用send()才方可。

一個栗子,經過post方法發送純文本給服務器

function postMessage(msg) {
    var request = new XMLHttpRequest(); // 新請求
    request.open('post', '/log.php');   // 用POST向服務器端發送腳本
    // 用請求主體發送純文本消息
    request.setRequestHeader('Content-Type', 'text.plain;charset=utf-8');   // 請求主體將是純文本

    request.send(msg);
    // 請求完成,咱們將忽略任何響應和任何錯誤
}

即上方定義了一個post請求,完成其發送,等待其服務器響應

取得響應

send()發送之後將會等待服務器響應,此時將不會阻塞。
在HTTP發送完成請求之後,下一步將會取得響應。
下面編寫函數獲取HTTP響應的onreadystatechange

// 發出一個HTTP GET請求獲取指定的URL的內容
// 當響應成功到達,驗證它是不是純文本
// 若是是,將會把它傳遞給指定的回調函數
function getText(url, callback) {
    var request = new XMLHttpRequest(); // 建立一個新請求
    request.open('GET', url);   // 建立一個指定待獲取的url
    request.onreadystatechange = () => {    // 當GRT請求完成之後,觸發該事件,產生回調函數
        // 若是請求完成,則它是成功的
        if (request.readyState === 4 && request.status === 200){    // 若是下載操做完成,即爲4,而且http狀態碼爲200
            var type = request.getResponnseHeader('Content-Type');  // 獲取HTTP頭部信息
            if (type.match(/^text/))    //正則匹配,肯定響應爲文本
                callback(request.responseText); // 回調函數,將返回的DOM樹,傳遞給回調函數
        }
    };

    request.send(null); // 發送
}

注意,該方式爲異步的,send方法不會阻塞其餘操做

同步響應

因爲其下載的問題,通常異步處理HTTP響應,可是同步也能夠,不過因爲客戶端js爲單線程的,當send()方法阻塞之後,將會致使瀏覽器的ui被凍結,若是鏈接的服務器過慢,將會致使用戶的操做出現問題。

方法直接open使用第三個參數爲false

響應解碼

當服務器響應的爲XML文檔的時候,其返回的值爲document對象,能使用操做節點的方式,對其進行操做
當服務器發送對象或者數組的結構化數據,如JSON,

使用JSON.parse 對結構化數據進行解析

下方書寫一個函數,進行結構化數據的解析

// 發起HTTP GET響應,得到指定的URL內容
// 當響應到達時,把他們解析後的XML Document對象,解析後的JSON對象
// 或者字符串形式傳遞給回調函數
function get(url, callback){
    var request = new XMLHttpRequest();
    request.open('GET', url);   // 指定url
    request.onreadystatechange = () => {    // 監聽器
        // 若是請求完成且成功
        if (request.readyState === 4 && request.status === 200) {
            // 得到響應請求
            var type = request.getResponseHeader('Content-Type');
            // 檢查類型
            // 當爲xml的時候
            if (type.indexOf('xml') !== -1 && request.responseXML)  // 確認是否爲xml
                calback(request.responseXML);   // 回調函數
            else if (type === "application/json")   // 若是頭部的信息爲JSON
                callback(JSON.parse(request.responseText)); // 將結果JSON格式解析
            else 
                callback(request.responseText); // 若是是字符串響應
        }
    };
    request.send(null); // 當即發送請求
}

對兩種數據解析,一種爲JSON格式,一種爲XML格式

ps 不建議使用eval

ps 因爲跨域的問題,只能讀取同源的數據,經過script腳本操縱HTTP腳本並實現加載並執行腳本

script 元素能發起跨域的HTTP請求

能使用request.overrideMimeType可以實現對MIME類型的更改

相關文章
相關標籤/搜索