天天看點

Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)

文章目錄

  • Web基礎知識
  • HTTP伺服器與用戶端(重要)
    • HTTP基礎
    • http子產品
    • 建立HTTP伺服器和用戶端
    • GET請求和POST請求

Web基礎知識

Web伺服器:

  • 又稱為網站伺服器,主要用于提供網上資訊浏覽服務
  • 常見的Web伺服器軟體有Apache HTTP Server(簡稱Apache)、Nginx等,Node内置有web伺服器

在Web伺服器中,請求資源又分為靜态資源和動态資源:

  • 靜态資源:隻要伺服器沒有修改這些檔案,用戶端每次請求到的都是同樣的内容。
  • 動态資源:是内容可以動态發生變化,每次請求都需要計算處理。

Http協定: 超文本傳輸協定,用于規範用戶端和伺服器之間以指定的格式進行資料互動。是一個基于 請求與響應 的協定。

  • Http請求:用戶端(浏覽器)向伺服器發送的請求(request)
  • Http響應:伺服器接收到用戶端的請求後做出的響應(response)

Http協定的請求資訊:

  • 請求行:請求方式、http協定的版本号 、請求資源的路徑
  • 請求頭:伺服器的URL、浏覽器類型、文本格式:作用是傳遞附加資訊
  • 實體内容

Http協定的響應資訊:

  • 響應行:http協定的版本号、狀态碼、字元描述(如OK)
  • 響應頭:響應文本的格式和長度、響應時間、是否允許跨域(附加在響應資訊中)
  • 實體内容:伺服器傳遞給用戶端的具體内容

Http協定的響應消息的狀态碼:

Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)

Http協定的響應消息檔案使用的通用格式: 大類别/具體類别

Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)

前後端互動:

  • 前端開發:浏覽器端程式開發
  • 後端開發:伺服器端程式開發,後端給前端提供服務

在動态網站中,許多功能是由前後端互動實作的。例如,使用者注冊和登入、發表評論、查詢積分、餘額等。這些操作可分為兩類,一類是向伺服器送出資料(表單互動),一類是向伺服器查詢資料( URL參數互動)。

  • 表單互動:用戶端向伺服器端送出表單資料,通過表單控件向伺服器端發送資料,伺服器收到後傳回處理結果
    Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)
  • URL參數互動:向伺服器送出一些請求資訊用來查詢資料,伺服器收到後傳回相應的結果
    Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)

HTTP伺服器與用戶端(重要)

HTTP基礎

HTTP協定: 超文本傳輸控制協定 ,通用的、無狀态的、與傳輸資料無關的協定(工作在應用層)

伺服器與用戶端進行互動的過程:

  1. 用戶端與伺服器建立TCP連接配接(HTTP協定是基于TCP協定實作的)
  2. 用戶端向伺服器發送請求
  3. 伺服器向用戶端傳回響應資訊
  4. 關閉HTTP連接配接

封包:

在HTTP請求和響應的過程中傳遞的資料塊就叫封包,包括要傳送的資料和一些附加資訊,并且要遵守規定好的格式

Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)

請求封包:

  • 請求方式: Request Method
    • GET 請求資料
    • POST 發送資料
  • 請求位址: Request URL

響應封包:

  • HTTP狀态碼:
    • 200 請求成功
    • 404 請求的資源沒有被找到
    • 500 伺服器端錯誤
    • 400 用戶端請求有文法錯誤
  • 内容類型:
    • text/html
    • text/css
    • application/javascript
    • image/jpeg
    • application/json

http子產品

http子產品: 用于實作HTTP通信

導入該子產品:

1、http.Server類:

http.Server類提供了實作HTTP伺服器的基本架構

實作的事件:

事件 描述
request 當有請求時會觸發該事件,提供兩個參數request和response,分别為http.IncomingMessage對象和http.ServerResponse對象,表示請求和響應的資訊
connect 用戶端請求HTTP的CONNECT方法時觸發該事件
connection 當TCP建立連接配接時觸發該事件,提供參數socket通常表示net.Socket對象
close 當伺服器關閉時觸發該事件
clientError 如果用戶端連接配接觸發error事件,則會在此處轉發

提供的方法:

  • server.listen() 用于啟動HTTP伺服器監聽連接配接
  • server.close() 用于停止伺服器接受新連接配接

主要實作的功能 :

  • 基于TCP連接配接建立一個網絡監聽器
  • 監聽自身的request請求事件

http.createServer()方法:

  • 文法格式:

    http.createServer([options][, requestlistener])

  • 要啟動HTTP伺服器,需要使用http.createServer()方法 建立一個http.Server對象

2、http.IncomingMessage類——傳入的資訊:

http.IncomingMessage對象(該類執行個體)由 http.Server或http.ClientRequest建立

實作的事件:

事件 描述
aborted 當請求中止時被觸發
close 表明底層連接配接已關閉

屬性:

Node.js 網絡程式設計 (上)Web基礎知識、實作HTTP及GET、POST的建立Web基礎知識HTTP伺服器與用戶端(重要)

3、http.ServerResponse類——響應:

指定要發送到用戶端的響應

實作的事件:

事件 描述
close 調用response.end()方法,或者能夠重新整理之前已終止的底層連接配接
finish 響應發送後觸發該事件

關于響應頭的額外方法 :

  • response.setHeader(name, value):設定一個特定的響應頭
  • getHeader(name):擷取已在響應中設定的某個響應頭
  • removeHeader(name):移除已在響應中設定的某個響應頭
  • response.addTrailers(headers):将HTTP尾部響應頭添加到響應中
  • response.writeHead(statusCode,[reasonPhrase],[headers]):将某個響應頭寫入請求

關于響應體的方法:

  • response.write(data,[encoding]):發送響應體
  • response.writeContinue():向用戶端發送HTTP/1.1 100 Continue消息,表示應發送請求體
  • response.end([data][,encoding][,callback]):結束響應,向伺服器表明已發送所有的響應頭和響應體。

屬性:

  • response.statusCode:重新整理響應頭時将發送到用戶端的狀态碼
  • response.statusMessage:重新整理響應頭時将發送到用戶端的狀态消息

4、http.ClientRequest類:

http.ClientRequest類提供了實作HTTP用戶端的基本架構

通過 http.request() 方法建立并傳回一個http.ClientRequest對象,作為HTTP用戶端,啟動、監控和處理來自伺服器的響應

實作的事件:

事件 描述
abort 當請求被用戶端中止時被觸發
connect 每次伺服器使用CONNECT方法響應請求時都會觸發該事件
continue 當伺服器發送“100 Continue”HTTP響應時被觸發
response 當收到此請求的響應時被觸發。此事件僅觸發一次
socket 将Socket配置設定給此請求後被觸發
timeout 當底層Socket因處于不活動狀态而逾時時被觸發。

用于請求頭的方法:

  • request.setHeader(name, value):設定一個特定的請求頭
  • request.getHeader(name):讀取請求中的一個請求頭
  • request.flushHeaders():重新整理請求頭

用于請求體的方法:

  • request.write(chunk[, encoding][, callback]):發送一個請求體的資料塊
  • request.end([data[, encoding]][, callback]):完成發送請求
  • request.abort():終止目前的請求
  • request.setTimeout(timeout,[callback]):為請求設定Socket逾時時間。

http.request()方法:

  • 文法格式:
    • http.request(options[, callback])

    • http.request(url[, options][,callback])

  • 建構一個HTTP用戶端,需使用http.request()方法建立一個ClientRequest對象

建立HTTP伺服器和用戶端

建立HTTP伺服器:

//導入http子產品
const http=require('http');
//建立http服務端   參數 req:請求對象   res:響應對象
//req:擷取用戶端請求資料   res:向用戶端發送響應資料
const server=http.createServer((req, res) => {
    console.log('用戶端的URL:'+req.url);
    //設定響應頭資訊  參數 狀态碼200:表示請求響應成功 content-type:響應資訊的格式和字元集(編碼格式)
    res.writeHead(200,{'content-type':'text/html;charset=utf-8'});
    res.write('<h2>Hello World!</h2>');
    res.end();
});
//綁定端口并啟動監聽
server.listen(8080,()=>{
    console.log('伺服器在8080端口上進行監聽');
});
           

建立HTTP用戶端:

//導入http子產品
const http=require('http');
//導入querystring子產品
const queryString=require('querystring');
//建立請求資料:通過queryString子產品的stringify方法将請求資料轉換為JSON格式
const postData=queryString.stringify({'msg':'你好,我是http用戶端'});
//建立請求的配置資訊:伺服器位址、端口、請求資源位址、請求方式、請求頭資訊
const options={
    hostname:'127.0.0.1',
    port:8080,
    path:'/upload',
    method:'post',
    headers:{
        'Content-Type':'application/x-www-form-urlencoded;charset=utf-8',
        'Content-Length':Buffer.byteLength(postData)
    }
}
//向伺服器端發送請求:建立請求對象
const req=http.request(options,(res) => {
    console.log(`狀态碼:${res.statusCode}`);
    console.log(`響應頭資訊:${JSON.stringify(res.headers)}`);
    res.setEncoding('utf8');
    res.on('data',chunk => {
        console.log(`響應體:${chunk}`);
    });
    res.on('end',()=>{
        console.log('請求結束');
    });
    res.on('error',(err => {
        console.log(err);
    }));
})
//将請求資料寫入請求體中
req.write(postData);
//請求結束
req.end();
           

GET請求和POST請求

請求參數: 用戶端向伺服器端發送請求時,有時需要攜帶一些客戶資訊,客戶資訊需要通過請求參數的形式傳遞到伺服器端。

GET請求:将請求參數包含在url中,即浏覽器位址欄中,例如:http://localhost:8080/index?age=12

  • 請求參數會儲存在浏覽器的曆史記錄中
  • 請求資料隻能通過URL進行編碼
  • 參數資料類型有限制,隻能接收ASCII字元
  • 不安全,不适合于傳遞敏感資訊

參數擷取需要借助系統子產品url,url子產品用來處理url位址,常用它的 parse() 方法轉化為對象

使用GET方式請求的情況:

  • 浏覽器位址欄
  • link标簽的href屬性
  • script标簽的src屬性
  • img标簽的src屬性
  • Form表單送出

GET方式建立伺服器:

//導入http url子產品
const http=require('http');
const url=require('url');
//建立伺服器
var server=http.createServer((req, res) => {
    //對用戶端url進行解碼
    let reqURL=decodeURI(req.url);
    //将url字元串轉換為url對象
    reqURL=url.parse(reqURL); //截取内容不容易區分
    console.log(reqURL);
    res.end('送出成功!');
});
//綁定并監聽端口
server.listen(8080);
           

GET方式建立用戶端:

//導入http子產品
const http=require('http');
//設定請求的配置資訊
const options={
    hostname:'127.0.0.1',
    port:8080,
    path:encodeURI('/index.html?age=12&stats=打開')
}
//建立get請求對象向伺服器發送get請求
http.get(options,res => {
    res.setEncoding('utf8');
    res.on('data',chunk => {
        console.log('響應資訊:'+chunk.toString());
    });
}).on('error',err => {
    console.log(err.message);
})
           

POST請求:将請求參數 包含在請求體(request body) 中

  • 請求參數不會儲存在浏覽器的曆史記錄中
  • 請求資料支援多種編碼格式
  • 對參數的資料類型無限制
  • 更安全,适合于傳遞敏感資訊

擷取POST參數需要使用data事件和end事件,使用 querystring系統子產品 将參數轉換為對象格式

使用POST方式請求的情況:

  • Form表單送出

POST方式建立伺服器:

const http=require('http');
const queryString=require('querystring');
//建立post請求的伺服器對象
var server=http.createServer((req, res) => {
    //data變量用來接收用戶端向服務端發送的請求資料
    let data='';
    req.on('data',chunk=>{
        //參數 chunk 中存放的是用戶端向伺服器發送的請求資料 是二進制格式 在和變量 data 連接配接時自動轉換為字元串
        data=data+chunk;
    })
    //給請求對象綁定綁定 end 事件 當請求結束時會觸發該事件
    req.on('end',()=>{
        //對請求資料進行解碼
        data=decodeURI(data);
        console.log('請求資料:'+data);
        //将請求資料轉換為對象
        let dataObj=queryString.parse(data);
        console.log('轉換後的請求資料:',dataObj);
        console.log('姓名:',dataObj.name);
        console.log('身份:',dataObj.title);
        res.end('送出成功!');
    });
});
server.listen(8080);
           

POST方式建立用戶端:

const http=require('http');
const queryString=require('querystring');
//将要送出給伺服器的資料轉換為查詢字元串(JSON格式資料)
var postData=queryString.stringify({
    'name':'張三',
    'title':'學生'
});
//建立配置資訊
var options={
    hostname:'127.0.0.1',
    port:8080,
    method:'post'
};
//建立post請求對象
//用request方法建立對象 在于options中 method為post
const req=http.request(options,res => {
    res.setEncoding('utf8');
    res.on('data',chunk => {
        console.log('響應資料:'+chunk.toString());
    });
});
//将請求的資料寫入請求對象
req.write(postData);
//結束請求
req.end();
           

學習文章:Node.js 網絡程式設計(下)實作TCP、UDP、WebSocket的建立

繼續閱讀