數(shù)據通信

2018-07-10 15:26 更新
Table of Contents generated with DocToc

數(shù)據通信

HTTP

HTTP 為一個通信協(xié)議。HTTP 客戶端發(fā)起請求并創(chuàng)建端口。HTTP 服務器在端口監(jiān)聽客戶端的請求。 HTTP 服務器在收到請求后則返回狀態(tài)和所請求的內容。

網頁瀏覽全過程 (粗淺流程)

  1. 域名解析
    1. 搜索瀏覽器自身 DNS 緩存
    2. 搜索操作系統(tǒng)自身 DNS 緩存(如上一級未找到或已失效)
    3. 讀取本地 HOST 文件 (如上一級未找到或已失效,/etc/hosts
    4. 瀏覽器發(fā)起 DNS 系統(tǒng)調用請求
      1. ISP 服務器查找自身緩存
      2. ISP 服務器發(fā)起迭代(逐域尋找需要的地址)請求
  2. 得到請求資源的 IP 地址
  3. 發(fā)起 HTTP “三次握手”(下面為一個超級簡化版)
    1. 建立連接,等待服務器確認
    2. 服務器接受請求,回復客戶
    3. 客戶端與服務器連接成功(TCP/IP 連接成功)
  4. 客戶根據協(xié)議發(fā)送請求
  5. 服務器更具請求返回客戶需求資源
  6. 客戶獲得資源

HTTP 事務

HTTP 請求報文

其中包括主機地址,HTTP 協(xié)議版本號。頭部由鍵值對組成。因為此請求為 GET 方法所以請求體為空。

HTTP 回復報文

其中包括 HTTP 版本號,狀態(tài)碼及狀態(tài)碼描述。頭部依然為鍵值對組成。主體則為 HTML 文件。

常用 HTTP 方法

常用方法

方法描述是否包含主題
GET從服務器獲取一份文檔
POST向服務器發(fā)送需要處理的數(shù)據
PUT將請求的主題部分儲存在服務器上
DELETE從服務器刪除一份文檔

不常用方法

方法描述是否包含主題
HEAD只從服務器獲取頭文檔的首部
TRACE對可能經過代理服務器傳送到服務器上的報文進行追蹤
OPTIONS決定可以在服務器上執(zhí)行的方法

URL 構成

http://www.github.com:8080/index.html?user=li-xinyang&lang=zh-CN#home
  |          |          |       |                  |              |
protocol     |          |       |                  |              |
          hostname     port     |                  |              |
              \        /    pathname             search          hash
                 host

可選部分包括

  • port
  • pathname
  • search
  • hash

NOTE:上面提供的 URL 地址僅為參考所用。

HTTP 版本

  • HTTP/0.9 1991年 HTTP 原型,存在設計缺陷
  • HTTP/1.0 第一個廣泛應用版本
  • HTTP/1.0+ 添加持久的 keep-alive 鏈接,虛擬主機支持,代理連接支持,成為非官方的事實版本
  • HTTP/1.1 校正結構性缺陷,明確語義,引入重要的新能優(yōu)化措施,刪除不好的特性(當前使用版本

NOTE:此文寫于2015年6月。

常見 HTTP 狀態(tài)碼

狀態(tài)碼描述代碼描述
200請求成功,一般用于 GET 和 POST 方法OK
301資源移動。所請求資源自動到新的 URL,瀏覽器自動跳轉至新的 URLMoved Permanently
304未修改。所請求資源未修改,瀏覽器讀取緩存數(shù)據Not Modified
400請求語法錯誤,服務器無法解析Bad Request
404未找到資源,可以設置個性“404頁面”Not Found
500服務器內部錯誤Internal Server Error

AJAX

AJAX(Asynchronous JavaScript and HTML)異步獲取數(shù)據的概念,由 Jesse James Garrett 在2005年提出。

AJAX 請求全過程

AJAX 調用

三部完成 AJAX 調用

  1. 創(chuàng)建 XHR 對象
  2. 處理返回數(shù)據及錯誤處理
  3. 發(fā)送請求
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function(callback) {
  if (xhr.readyState === 4) {
    if ((xhr.status >== 200 && xhr.status < 300) || xhr.status === 304) {
      callback(xhr.responseText);
    } else {
      console.error('Request was unsuccessful: ' + xhr.status);
    }
  }
}

xhr.open('get', 'exmaple.json', true);
xhr.setRequestHeader('myHeader', 'myValue');
xhr.send(null);

NOTE:xhr.onload 只針對當 readyState === 4 和 status === 200 時的事件。

open
xhr.open(method, url[, async = true]);
  • method 為上面說過的 HTTP 方法(例如,GET、POST)
  • url 為資源地址
  • async 默認為真,用于設置異步請求
setRequestHeader
xhr.setRequestHeader('myHeader', 'myValue');

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

用于設置頭部的鍵值對。

send
xhr.send([data=null]);

xhr.send()

數(shù)據可包含字符串或表單數(shù)控,但需要提前為 RequestHeader 做設置。

請求參數(shù)序列化

將查詢參數(shù)使用字符串,跟入資源地址中。

xhr.open('get', 'example.json?' + 'name=value&age=value', true);

對象轉換字符串的函數(shù)實現(xiàn)

function serialize(data) {
  if (!data) return '';
  var pairs = [];
  for (var name in data) {
    if (!data.hasOwnProperty(name)) continue;
    if (typeof data[name] === 'function') continue;
    var value = data[name].toString();
    name = encodeURIComponent(name);
    value = encodeURIComponent(value);
    pairs.push(name + '=' + value);
  }
  return pairs.join('&');
}

GET 請求

var url = 'example.json?' + serialize(formData);
xhr.open('get', url, true);
xhr.send(null);

POST 請求

查詢參數(shù)需要作為 send() 的存數(shù)傳入。

xhr.open('get', 'example.json', true);
xhr.send(serialize(formData));

同源策略

兩個頁面擁有相同的協(xié)議(Protocol)、端口(Port)、和主機(host)那么這兩個頁面就是屬于同一個源(Origin)。

http://www.github.com:8080/index.html?user=li-xinyang&lang=zh-CN#home
  |          |          |       |                  |              |
protocol     |          |       |                  |              |
          hostname     port     |                  |              |
              \        /    pathname             search          hash
                 host
|-----完全一致則同源------|

跨域資源訪問

不滿足同源策略的資源訪問均屬于跨域資源訪問,W3C 定義了 CORS?,F(xiàn)代瀏覽器已經實現(xiàn)了 CORS 的支持。

CORS 原理實現(xiàn)圖

其他跨域技術
  • Frame 代理
  • JSONP
  • Comet
  • Web Sockets
  • ...

Frame 代理

關于 Frame 代理的更多內容在這里。

優(yōu)點:

  • 參照 CORS 標準
  • 支持各種請求方法 GET POST PUT DELETE

缺點:

  • 需要在目標服務器防止代理文件(造成延時)
  • 低版本在大并發(fā)消息通信機制會產生延時

JSONP

全程為 JSON with Padding(填充式 JSON),它利用 <script> 可以跨域的原理。請求一段 JavaScript 代碼,然后執(zhí)行 JavaScript 代碼來實現(xiàn)跨域。

function handleResponse(response) {
  alert(response.name);
}

var script = document.createElement('script');
script.src = 'http://localhost:3000/json?callback=handleResponse';
document.body.insertBefore(script, document.body.firstChild);


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號