日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Node.js 入门详解 (三)

發布時間:2024/9/27 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Node.js 入门详解 (三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 1. 初識Express
    • 1.1 Express簡介
      • 1.1.1 什么是Express
      • 1.1.2 進一步理解 Express
      • 1.1.3 Express能做什么
      • 1.1.4 Express 中的數據分類
    • 1.2 Express 的基本使用
      • 1.2.1 安裝
      • 1.2.2 創建基本的web服務器
      • 1.2.3 監聽 GET請求
      • 1.2.4 監聽 post 請求
      • 1.2.5 把內容響應給客戶端
      • 1.2.6 獲取 URL 中攜帶的查詢參數
      • 1.2.7 獲取 URL中的動態參數
    • 1.3 托管靜態資源
      • 1.3.1 express.static()
      • 1.3.2 托管多個靜態資源項目
      • 1.3.3 掛載路徑前綴
    • 1.4 nodemon
      • 1.4.1 nodemon的作用
      • 1.4.2 安裝nodemon
      • 1.4.3 使用nodemon
  • 2. Express路由
    • 2.1 路由的概念
      • 2.1.1 什么是路由
      • 2.1.2 現實生活中的路由
      • 2.1.3 Express中的路由
      • 2.1.4 Express中的路由的例子
      • 2.1.5 路由的匹配過程
    • 2.2 路由的使用
      • 2.2.1 最簡單的用法
      • 2.2.2 模塊化路由
      • 2.2.3 創建路由模塊
      • 2.2.4 注冊路由模塊
      • 2.2.5 為路由模塊添加前綴
  • 3. 中間件
    • 3.1 中間件的概念
      • 3.1.1 什么是中間件
      • 3.1.2 . 現實生活中的例子
      • 3.1.3 . Express 中間件的調用流程
      • 3.1.4 . Express 中間件的格式
      • 3.1.5 . next 函數的作用
    • 3.2 中間件的初體驗
      • 3.2.1 定義中間件函數
      • 3.2.2 全局生效 的中間件
      • 3.2.3 定義全局中間件的簡化形式
      • 3.2.4 中間件的 作用
      • 3.2.5 定義多個全局中間件
      • 3.2.6 局部生效 的中間件
      • 3.2.7 定義多個局部中間件
      • 3.2.8 了解中間件的 5 個 使用注意事項
    • 3.3 中間件的分類
      • 3.3.1 應用級別的中間件
      • 3.3.2 路由級別的中間件
      • 3.3.3 錯誤級別 的中間件
      • 3.3.4 Express 內置 的中間件
      • 3.3.5 第三方 的中間件
    • 3.4 自定義中間件
      • 3.4.1 需求描述與實現步驟
      • 3.4.2 定義中間件
      • 3.4.3 監聽 req 的 data 事件
      • 3.4.4 監聽 req 的 end 事件
      • 3.4.5 使用 querystring 模塊解析請求體數據
      • 3.4.6 將解析出來的數據對象掛載為 req.body
      • 3.4.7 將自定義中間件封裝為模塊
  • 4. 使用Express寫接口
    • 4.1 創建基本的服務器
    • 4.2 創建API路由模塊
    • 4.3 編寫 GET 接口
    • 4.4 編寫 POST 接口
    • 4.5 CORS跨域資源共享
      • 4.5.1 接口的 跨域問題
      • 4.5.2 使用 cors 中間件 解決跨域問題
      • 4.5.3 什么是 CORS
      • 4.5.4 . CORS 的注意事項
      • 4.5.5 . CORS 響應頭部 Access-Control-Allow-Origin
      • 4.5.6 . CORS 響應頭部 Access-Control-Allow-Headers
      • 4.5.7 . CORS 響應頭部 Access-Control-Allow-Methods
      • 4.5.8 . CORS 請求的分類
      • 4.5.9 簡單請求
      • 4.5.10 預檢請求
      • 4.5.11 . 簡單請求 和 預檢請求 的區別
    • 4.6 JSONP接口
      • 4.6.1 JSONP 的概念與特點(回顧)
      • 4.6.2 創建 JSONP 接口的注意事項
      • 4.6.3 實現 JSONP 接口的步驟
      • 4.6.4 實現 JSONP 接口的具體代碼
      • 4.6.5 在網頁中使用 jQuery 發起 JSONP 請求


1. 初識Express


1.1 Express簡介

1.1.1 什么是Express

官方給出的概念:Express 是 基于 Node.js 平臺 快速開放極簡Web 開發框架

通俗的理解:Express 的作用和 Node.js 內置的 http 模塊類似,是專門用來創建 Web 服務器的

Express的本質 :就是一個 npm 上的第三方包,提供了快速創建 Web 服務器的便捷方法。


Express 的中文官網:https://www.expressjs.com.cn/


1.1.2 進一步理解 Express

:不使用 Express 能否創建 Web 服務器?
:能,使用 Node.js 提供的原生 http 模塊即可。

:既生瑜何生亮(有了 http 內置模塊,為什么還有用 Express?
:http 內置模塊用起來很復雜,開發效率低; Express 是基于內置的 http 模塊進一步封裝出來的,能夠極大的提高開發效率。

:http 內置模塊與 Express 是什么關系?
:類似于瀏覽器中 Web API 和 jQuery 的關系。后者是基于前者進一步封裝出來的。

1.1.3 Express能做什么

對于前端程序員來說,最常見的 兩種 服務器,分別是:

  • Web 網站服務器 :專門對外提供 Web 網頁資源的服務器;
  • API 接口服務器 :專門對外提供 API 接口的服務器。

使用Express ,我們可以方便、快速的創建 Web 網站 的服務器或 API 接口 的服務器。


1.1.4 Express 中的數據分類

在Express中,數據分成 3 種:表單數據查詢字符串數據url里攜帶的數據

  • 表單數據:通過 req.body進行獲取;
  • 查詢字符串數據:通過req.query 進行獲取;
  • URL里攜帶的數據:通過req.params進行獲取。

1.2 Express 的基本使用

1.2.1 安裝

在項目所處的目錄中,運行如下的終端命令,即可將express 安裝到項目中使用:

npm i express@4.17.1

1.2.2 創建基本的web服務器

// 1、導入 express const express = require('express') // 2、創建 web 服務器 const app = express()// 3、調用 app.listen(端口號,啟動成功后的回調函數),啟動服務器 app.listen(80,() => {console.log('express server running at http://127.0.0.1') })

1.2.3 監聽 GET請求

通過 app.get () 方法,可以監聽客戶端的 GET 請求,具體的語法格式如下:

// 參數1:客戶端請求的 URL 地址 // 參數2:請求對應的處理函數 // req:請求對象(包含了與請求相關的屬性和方法) // res:響應對象(包含了與響應相關的屬性與方法) app.get('請求URL'function(req,res) { /* 處理函數 */})

1.2.4 監聽 post 請求

通過 app.post () 方法,可以監聽客戶端的 POST 請求,具體的語法格式如下:

// 參數1:客戶端請求的 URL 地址 // 參數2:請求對應的處理函數 // req:請求對象(包含了與請求相關的屬性和方法) // res:響應對象(包含了與響應相關的屬性與方法) app.post('請求URL'function(req,res) { /* 處理函數 */})

1.2.5 把內容響應給客戶端

通過 res.send () 方法,可以把處理好的內容,發送給客戶端:

app.get('/user',(req,res) => {// 向客戶端發送 JSON對象res.send({ name:'zs', age:20, gender:'男' }) })app.post('/user', (req,res) =>{// 向客戶端發送文本內容res.send('請求成功') })

注: res.send()方法,既可以響應JSON對象,也可以響應一段普通文本。

運行 node 命令,啟動服務器之后,可借助接口調試工具 Postman,來測試這兩次請求。

發起 GET 請求如下:



發起POST 請求如下:



可以看到 GET 和 POST 的請求,客戶端分別響應回了一段JSON格式的數據對象和文本字符串。

1.2.6 獲取 URL 中攜帶的查詢參數

通過 req.query 對象,可以訪問到客戶端通過查詢字符串 的形式,發送到服務器的參數:

app.get('/', (req,res) =>{// 客戶端使用 ?name=zs&age=20 這種查詢字符串形式,發送到服務器的參數// 通過 req.query 可以獲取到客戶發送過來的查詢參數// 注意:默認情況下,req.query 是一個空對象console.log(req.query);res.send(req.query) })

1.2.7 獲取 URL中的動態參數

通過 req.params 對象,可以訪問到 URL 中,通過:(冒號)匹配到的 動態參數

// 注意:這里的 :id 是一個動態的參數 app.get('/user/:id', (req, res) => {// req.params 是動態匹配到的 URL 參數。默認也是一個空對象console.log(req.params);res.send(req.params) })


:id - 冒號后面是動態參數的名稱,理論上可以任意(合法即可)。可以跟多個參數。

例如:http://127.0.0.0/user/:id/:username,發起請求后,服務器端匹配如圖:



1.3 托管靜態資源

1.3.1 express.static()

express 提供了一個非常好用的函數,叫做 express.static(),通過它,我們可以非常方便地創建一個靜態資源服務器

例如,通過app.use(express.static('public'))就可以將 public 目錄下的圖片、CSS 文件、JavaScript 文件對外開放訪問了:


現在,就可以訪問到 public 目錄中的所有文件了:

http://localhost:3000/images/bg.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/login.js


📌注意:
Express 在 指定的 靜態目錄中查找文件,并對外提供資源的訪問路徑。因此,存放靜態文件的目錄名未包含在 URL 中


1.3.2 托管多個靜態資源項目

如果要托管多個靜態資源目錄,就要多次調用 express.static() 函數:


訪問靜態資源文件時,express.static() 函數會根據目錄的添加順序查找所需的文件。

1.3.3 掛載路徑前綴

如果希望在托管的靜態資源訪問路徑之前,掛載路徑前綴 ,則可以使用如下的方式:

app.use('public',express.static('public'))

這樣,就可以通過帶有/public 前綴地址來訪問 public 目錄中的文件了:

http://localhost:3000/public /images/kitten.jpg
http://localhost:3000/public /css/style.css
http://localhost:3000/public /js/app.js


1.4 nodemon

1.4.1 nodemon的作用

在編寫調試 Node.js 項目的時候,如果修改了項目的代碼,則需要頻繁的手動 close 掉,然后再重新啟動,非常繁瑣。

現在,我們可以使用 nodemon(https://www.npmjs.com/package/nodemon)這個工具,它能夠 監聽項目文件的變動 ,當代碼被修改后 nodemon 會 自動幫我們重啟項目 ,極大方便了開發和調試。

1.4.2 安裝nodemon

在終端中,運行如下命令,即可將 nodemon 安裝為全局可用的工具:

1.4.3 使用nodemon

當基于 Node.js 編寫了一個網站應用的時候,傳統的方式,是運行 node app.js 命令,來啟動項目。這樣做的壞處是:代碼被修改之后,需要手動重啟項目。

現在,我們可以將 node 命令替換為 nodemon 命令,使用 nodemon app.js 來啟動項目。這樣做的好處是:代碼被修改之后,會被 nodemon 監聽到,從而實現自動重啟項目的效果。



2. Express路由

2.1 路由的概念

2.1.1 什么是路由

廣義上來講,路由就是 映射關系(或對應關系)。

2.1.2 現實生活中的路由



2.1.3 Express中的路由

在 Express 中,路由指的是客戶端的請求服務器處理函數之間的映射關系

Express 中的路由分 3 部分:

  • 請求的類型
  • 請求的 URL 地址
  • 處理函數

格式如下:



2.1.4 Express中的路由的例子

// 匹配 GET 請求,且請求 URL 為 / app.get('/',function (req,res) {res.send('Hellow World!') }) // 匹配 POST 請求,且請求 URL 為 / app.post('/',function(req,res){res.send('Got a POST request') })

2.1.5 路由的匹配過程

每當一個請求到達服務器之后,需要先經過路由的匹配 ,只有匹配成功之后,才會調用對應的處理函數。

在匹配時,會按照路由的順序進行匹配,如果請求類型請求的 URL 同時匹配成功,則 Express 會將這次請求,轉交給對應的 function 函數進行處理。



路由匹配的注意點:

  • 按照定義的 先后順序 進行匹配;(如果前面的路由匹配成功,則終止后面的路由匹配。)
  • 請求類型請求的URL 同時匹配成功,才會調用對應的處理函數。

  • 2.2 路由的使用

    2.2.1 最簡單的用法

    在 Express 中使用路由最簡單的方式,就是把路由掛載到 app 上

    1)cd 根目錄名稱(本示例是MyCase目錄下的testm文件夾),并初始化一個package.json包管理文件。

    cd testm npm init -y

    如下圖:

    2)安裝Express(注意,根據前面的約定,需安裝指定的版本號,因此需加上@4.17.1)

    npm i express@4.17.1

    如下圖:

    安裝完畢后,項目根目錄生成了 package.json、package-lock.json以及node_modules文件夾。

    3)創建路由對應的 JavaScript 文件。示例代碼如下:


    通過 nodemon 命令將項目運行起來

    4)借助 Postman[下載地址]這個軟件模擬發起客戶端請求,測試這兩個路由能否正常生效。

    • GET 請求如下圖:



    • POST 請求如下圖:


    【測試結果】:GET 和 POST 均能正常請求成功,服務器也返回了對應的文本內容。

    這種把路由掛載 app 實例上的方式,實際開發中很少用。因為隨著代碼的增多,會掛載越來越多的路由,文件體積會越來越大。


    2.2.2 模塊化路由

    為了方便對路由進行模塊化的管理,Express 不建議 將路由直接掛載到 app 上,而是 推薦將路由抽離為單獨的模塊

    將路由抽離為單獨模塊的步驟如下:

  • 創建路由模塊對應的 .js 文件;
  • 調用 express.Router() 函數創建路由對象;
  • 向路由對象上掛載具體的路由;
  • 使用 module.exports 向外共享路由對象;
  • 使用 app.use() 函數注冊路由模塊。

  • 2.2.3 創建路由模塊


    🔔 注意:創建路由對象時,Router首字母大寫。
    app.use()函數的作用,是用來注冊全局中間件

    2.2.4 注冊路由模塊


    注冊好路由,確保啟動服務器的情況下,打開Postman 接口測試工具,可以檢測是否創建成功。

    2.2.5 為路由模塊添加前綴

    類似于托管靜態資源時,為靜態資源統一掛載訪問前綴一樣,路由模塊添加前綴的方式也非常簡單:




    3. 中間件

    3.1 中間件的概念

    3.1.1 什么是中間件

    中間件(Middleware ),特指 業務流程中間處理環節

    3.1.2 . 現實生活中的例子

    在處理污水的時候,一般都要經過三個處理環節 ,從而保證處理過后的廢水,達到排放標準。



    處理污水的這三個中間處理環節,每一個環節都有輸入和輸出(上一節的輸出作為一下節的輸入),這樣的環節就可以叫做中間件。

    3.1.3 . Express 中間件的調用流程

    當一個請求到達 Express 的服務器之后,可以連續調用多個中間件,從而對這次請求進行 預處理




    3.1.4 . Express 中間件的格式

    Express 的中間件, 本質 上就是一個 function 處理函數, Express 中間件的格式如下:



    注意:中間件函數的形參列表中,必須包含 next 參數 。而路由處理函數中只包含 req 和 res 。

    3.1.5 . next 函數的作用

    next 函數 是實現 多個中間件連續調用 的關鍵,它表示把流轉關系 轉交 給下一個 中間件路由




    3.2 中間件的初體驗

    3.2.1 定義中間件函數

    可以通過如下的方式,定義一個最簡單的中間件函數:



    3.2.2 全局生效 的中間件

    客戶端發起的任何請求 ,到達服務器之后 都會觸發的中間件 ,叫做全局生效的中間件。

    通過調用app.use(中間件函數 ),即可定義一個 全局生效 的中間件,示例代碼如下:



    3.2.3 定義全局中間件的簡化形式



    3.2.4 中間件的 作用

    多個中間件之間,共享同一份 req 和 res 。基于這樣的特性,我們可以在 上游 的中間件中, 統一 為 req 或 res對象添加自定義的屬性或方法 ,供下游 的中間件或路由進行使用。




    3.2.5 定義多個全局中間件

    可以使用 app.use () 連續定義多個 全局中間件。客戶端請求到達服務器之后,會按照中間件 定義的先后順序 依次進行調用,示例代碼如下:


    3.2.6 局部生效 的中間件

    不使用 app.use() 定義的中間件,叫做局部生效的中間件 ,示例代碼如下:


    3.2.7 定義多個局部中間件

    可以在路由中,通過如下兩種 等價 的方式, 使用多個局部中間件:


    3.2.8 了解中間件的 5 個 使用注意事項

  • 一定要在 路由之前 注冊中間件;
  • 客戶端發送過來的請求, 可以連續調用多個中間件進行處理;
  • 執行完中間件的業務代碼之后, 不要忘記調用 next() 函數
  • 為了 防止代碼邏輯混亂,調用 next() 函數后不要再寫額外的代碼;
  • 連續調用多個中間件時,多個中間件之間, 共享 req 和 res 對象。

  • 3.3 中間件的分類

    為了方便理解記憶中間件的使用, Express 官方把常見的中間件用法,分成了 5 大類 ,分別是:

  • 應用級別的中間件;
  • 路由級別的中間件;
  • 錯誤級別的中間件;
  • Express 內置的中間件;
  • 第三方的中間件

  • 3.3.1 應用級別的中間件

    通過app.use() 或 app.get() 或 app.post() 綁定到 app 實例上的中間件 ,叫做應用級別的中間件,代碼示例如下:



    3.3.2 路由級別的中間件

    綁定到express.Router() 實例上的中間件,叫做路由級別的中間件。它的用法和應用級別中間件沒有任何區別。只不過, 應用級別中間件是綁定到 app 實例上路由級別中間件綁定到 router 實例上 ,代碼示例如下:



    3.3.3 錯誤級別 的中間件

    錯誤級別中間件的作用 :專門用來捕獲整個項目中發生的異常錯誤,從而防止項目異常崩潰的問題。
    格式:錯誤級別中間件的 function 處理函數中, 必須有 4 個形參 ,形參順序從前到后,分別是 (err , req, res, next)。


    🔔 注意:

    錯誤級別的中間件,必須注冊在所有路由之后

    3.3.4 Express 內置 的中間件

    自 Express 4.16.0 版本開始, Express 內置了 3 個 常用的中間件,極大的提高了 Express 項目的開發效率和體驗:

  • express.static 快速托管靜態資源的內置中間件,例如: HTML 文件、圖片、 CSS 樣式等(無兼容性);
  • express.json 解析 JSON 格式的請求體數據( 有兼容性 ,僅在 4.16.0+ 版本中可用);
  • express.urlencoded 解析 URL encoded 格式的請求體數據( 有兼容性 ,僅在 4.16.0+ 版本中可用)


  • 3.3.5 第三方 的中間件

    非 Express 官方內置的,而是由第三方開發出來的中間件,叫做第三方中間件。在項目中,我們可以 按需下載配置 第三方中間件,從而提高項目的開發效率。

    例如:在express@4.16.0 之前的版本中,經常使用 body parser 這個第三方中間件,來解析請求體數據。使用步驟如下:

  • 運行 npm install body parser 安裝中間件;
  • 使用 require 導入中間件;
  • 調用 app.use() 注冊并使用中間件。

  • 🔔 注:

    Express 內置的 express.urlencoded 中間件,就是基于 body parser 這個第三方中間件進一步封裝出來的。

    3.4 自定義中間件

    3.4.1 需求描述與實現步驟

    自己 手動模擬 一個類似于 express.urlencoded 這樣的中間件,來 解析 POST 提交到服務器的表單數據

    實現步驟:

  • 定義中間件;
  • 監聽 req 的 data 事件;
  • 監聽 req 的 end 事件;
  • 使用 querystring 模塊解析請求體數據;
  • 將解析出來的數據對象掛載為 req.body;
  • 將自定義中間件封裝為模塊

  • 3.4.2 定義中間件

    使用 app.use() 來定義全局生效的中間件,代碼如下:


    3.4.3 監聽 req 的 data 事件

    中間件中,需要監聽 req 對象的 data 事件,來獲取客戶端發送到服務器的數據。

    如果數據量比較大,無法一次性發送完畢,則客戶端會 把數據切割后 分批發送到服務器。所以 data 事件可能會觸發多次,每一次觸發 data 事件時, 獲取到數據只是完整數據的一部分 ,需要手動對接收到的數據進行拼接。



    3.4.4 監聽 req 的 end 事件

    當請求體數據 接收完畢 之后,會自動觸發 req 的 end 事件

    因此,我們可以在req 的 end 事件中,拿到并處理完整的請求體數據 。示例代碼如下:


    現在就可以用 Postman 來模擬客戶端發起 post 請求,填寫完模擬數據,點擊 send ,如圖:

    可以看到服務端沒有響應,但在終端里,已經有打印出請求體的字符串,如下所示:


    3.4.5 使用 querystring 模塊解析請求體數據

    Node.js 內置了一個 querystring 模塊專門用來處理查詢字符串 。通過這個模塊提供的 parse() 函數,可以輕松把查詢字符串,解析成對象的格式。示例代碼如下:



    3.4.6 將解析出來的數據對象掛載為 req.body

    上游中間件下游中間件及路由 之間, 共享同一份 req 和 res 。因此,我們可以將解析出來的數據,掛載為 req 的自定義屬性,命名為 req.body ,供下游使用。示例代碼如下:



    3.4.7 將自定義中間件封裝為模塊

    為了優化代碼的結構,我們可以把自定義好的中間件函數拆分出去,封裝為獨立的模塊 ,示例代碼如下:


    【自定義中間件的完整代碼】
    1)拆分出去封裝好的 custom-body-parser 模塊:

    // 導入 Node.js 內置的 querystring 模塊 const qs = require('querystring');// 解析表單數據的中間件函數 const bodyParser = (req, res, next) => {// 定義中間件的具體業務邏輯// 1、定義一個 str 字符串,專門用來存儲客戶端發送過來的請求體let str = '';// 2、監聽 req 的 data 事件req.on('data', (chunk) => {str += chunk;});// 3、監聽 req 的 end 事件req.on('end', () => {// str 中是完整的請求體數據// console.log(str);// TODO:把字符串格式的請求體數據,解析成對象格式const body = qs.parse(str);// 將 body 掛載為 req 的屬性req.body = body;next();}) }// 向外暴露成員(解析請求體數據的中間件函數) module.exports = bodyParser;

    2)拆分后的中間件 + custom-body-parser 模塊導入與使用:

    // 導入 express const express = require('express');// 創建 express 服務器實例 const app = express();// 1、導入自己封裝的中間件模塊 const myBodyParser = require('./custom-body-parser'); // 2、將自定義中間件函數,注冊為全局可用的中間件 app.use(myBodyParser);app.post('/user', (req, res) => {res.send(req.body); })// 調用 app.listen方法 指定端口號并啟動 web 服務器 app.listen(80, () => {console.log('Express server running at http://127.0.0.1'); })

    4. 使用Express寫接口


    4.1 創建基本的服務器



    4.2 創建API路由模塊



    4.3 編寫 GET 接口



    4.4 編寫 POST 接口


    🔔注意:
    1、如果要獲取 URL-encoded 格式的請求體數據,必須配置中間件 ;
    2、需將此中間件注冊在路由模塊注冊之前方能生效。

    app.use(express.urlencoded ({ extended: false}))

    調用urlencoded()方法期間指定的配置對象 {extended: false}是固定寫法

    【完整代碼】

    1)服務器創建、模塊化路由導入與注冊

    // 導入express const express = require('express'); // 創建服務器 const app = express();// 導入路由模塊 const router = require('./router'); // 注冊 RUL-encoded 中間件 app.use(express.urlencoded ({ extended: false})) // 注冊路由模塊 app.use('/api',router);// 啟動服務器 app.listen(80, () => {console.log('server running at http://127.0.0.1'); })

    2)API 接口模塊化路由

    // 導入 express 模塊 const express = require('express'); // 調用express.Router 方法生成路由實例 const router = express.Router();// 掛載對應的路由 router.get('/get', (req, res) => {// 通過 req.query 獲取客戶端通過查詢字符串,發送到服務器的數據const query = req.query;// 調用 res.send() 方法,向客戶端響應處理的結果res.send({status: 0, // 0 表示處理成功,1 表示處理失敗msg: 'GET 請求成功!', // 狀態描述data: query // 需要響應給客戶端的數據}); });// 定義 POST 接口 router.post('/post', (req, res) => {// 通過 req.body 獲取請求體中包含的 url-encoded 格式的數據const body = req.body// 調用 res.send() 方法向客戶端響應數據res.send({status: 0,msg: 'POST 請求成功!',data: body}); });// 暴露 router 供外界使用 module.exports = router;

    4.5 CORS跨域資源共享


    4.5.1 接口的 跨域問題

    實際上,前面編寫的GET和 POST接口,存在一個很嚴重的問題:不支持跨域請求

    新建一個 html 文件,測試跨域的問題

    <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script> </head><body><button id="btnGET">GET</button><button id="btnPOST">post</button><script>$(function() {// 1、測試 GET 接口$('#btnGET').on('click', function() {$.ajax({type: 'GET',url: 'http://127.0.0.1/api/get',data: {name: 'zs',age: 20},success: function(res) {console.log(res);}})})// 2、測試 POST 接口$('#btnPOST').on('click', function() {$.ajax({type: 'POST',url: 'http://127.0.0.1/api/post',data: {bookname: '水滸傳',author: '施耐奄'},success: function(res) {console.log(res);}})})})</script> </body></html>

    當點擊按鈕會,就會拋出以下錯誤提示:

    首先,我們知道只要協議、域名、端口號任何一項不同,都存在跨域問題。因此,本案例之所以報錯,就是因為跨域的問題。


    解決接口跨域問題的方案( 主要下面 2 種):

  • CORS (主流的解決方案,實際開發推薦方案;)
  • JSONP(有缺陷的解決方案:只支持 GET 請求)。

  • 4.5.2 使用 cors 中間件 解決跨域問題

    cors是 Express 的一個第三方中間件。通過安裝和配置 cors 中間件,可以很方便地解決跨域問題。

    使用步驟( 分 3 步):

  • npm install cors // 安裝中間件
  • const cors = require('cors') // 導入中間件
  • 在路由之前調用: app.use(cors()) // 配置中間件(一定要在路由之前配置)。

  • 4.5.3 什么是 CORS

    CORS(Cross-Origin Resource Sharing ,即跨域資源共享)由一系列 HTTP 響應頭 組成,這些 HTTP 響應頭決定瀏覽器是否阻止前端 JavaScript 代碼跨域獲取資源

    瀏覽器的 同源安全策略 默認會阻止網頁“跨域”獲取資源。但如果接口服務器 配置了 CORS 相關的 HTTP 響應頭,就可以 解除瀏覽器端的跨域訪問限制




    4.5.4 . CORS 的注意事項

  • CORS 主要在 服務器端 進行配置。客戶端瀏覽器 無須做任何額外的配置 ,即可請求開啟了 CORS 的接口;
  • CORS 在瀏覽器中 有兼容性 。只有支持 XMLHttpRequest Level2 的瀏覽器,才能正常訪問開啟了 CORS 的服務端接口(例如: IE10+ 、 Chrome4+ 、 FireFox3.5+FireFox3.5+)。

  • 4.5.5 . CORS 響應頭部 Access-Control-Allow-Origin

    響應頭部中可以攜帶一個 Access-Control-Allow-Origin 字段,其語法如下:


    其中,origin 參數的值指定了 允許訪問該資源的外域 URL


    例如,下面的字段值將 只允許 來自 http://itcast.cn 的請求:



    如果指定了Access-Control-Allow-Origin 字段的值為 通配符 **,表示允許來自任何域的請求,示例代碼如下:



    4.5.6 . CORS 響應頭部 Access-Control-Allow-Headers

    默認情況下,CORS 支持 客戶端向服務器 發送如下的 9請求頭

    Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width 、Width、Content-Type(值僅限于 text/plain 、 multipart/form-data 、 application/x-www-form-urlencoded 三者之一)

    如果客戶端向服務器發送了額外的請求頭信息 ,則需要在 服務器端 ,通過 Access-Control-Allow-Headers 對額外的請求頭進行聲明 ,否則這次請求會失敗!



    4.5.7 . CORS 響應頭部 Access-Control-Allow-Methods

    默認情況下,CORS僅支持客戶端發起GETPOSTHEAD請求。

    如果客戶端希望通過 PUTDELETE 等方式請求服務器的資源,則需要在服務器端,通過 Access-Control-Alow-Methods 指明實際請求所允許使用的 HTTP 方法

    示例代碼:


    4.5.8 . CORS 請求的分類

    客戶端在請求 CORS接口 時,根據 請求方式請求頭 的不同,可以將 CORS 的請求分為 兩大類 ,分別是:

    • 簡單請求;
    • 預檢請求。

    4.5.9 簡單請求

    同時滿足以下兩大條件的請求,就屬于簡單請求

  • 請求方式:GET 、 POST 、 HEAD 三者之一
  • HTTP 頭部信息不超過以下幾種字段:無自定義頭部字段、Accept、Accept-Language、Content-Language、DPR、Downlink、 Save-Data、Viewport-Width、Width、Content-Type(只有三個值 application/x-www-form-urlencoded、 multipart/form-data、text/plain)

  • 4.5.10 預檢請求

    只要符合以下任何一個條件的請求,都需要進行預檢請求:

  • 請求方式為 GET、POST、HEAD之外的請求 Method 類型
  • 請求頭中 包含自定義頭部字段
  • 向服務器發送了 application/json 格式的數據
  • 在瀏覽器與服務器正式通信之前,瀏覽器會 先發送 OPTION 請求進行預檢,以獲知服務器是否允許該實際請求 ,所以這一次的 OPTION 請求稱為“預檢請求”。 服務器成功響應預檢請求后,才會發送真正的請求,并且攜帶真實數據

    4.5.11 . 簡單請求 和 預檢請求 的區別

    簡單請求的特點:客戶端與服務器之間 只會發生一次請求

    預檢請求的特點:客戶端與服務器之間會發生兩次請求 OPTION 預檢請求成功之后,才會發起真正的請求

    4.6 JSONP接口

    4.6.1 JSONP 的概念與特點(回顧)

    概念
      瀏覽器端通過 <script> 標簽的 src 屬性,請求服務器上的數據,同時,服務器返回一個函數的調用。這種請求數據的方式叫做 JSONP 。

    特點

  • JSONP 不屬于真正的 Ajax 請求,因為它沒有使用 XMLHttpRequest 這個對象。
  • JSONP 支持 GET 請求,不支持 POST、PUT、DELETE 等請求。

  • 4.6.2 創建 JSONP 接口的注意事項

    如果項目中已經配置了 CORS 跨域資源共享,為了 防止沖突,必須在配置 CORS 中間件之前聲明 JSONP 的接口 。否則JSONP 接口會被處理成開啟了 CORS 的接口。示例代碼如下:



    4.6.3 實現 JSONP 接口的步驟

  • 獲取 客戶端發送過來的 回調函數的名字
  • 得到要 通過 JSONP 形式 發送給客戶端的數據
  • 根據前兩步得到的數據, 拼接出一個函數調用的字符串
  • 把上一步拼接得到的字符串,響應給客戶端的 <script> 標簽進行解析執行。

  • 4.6.4 實現 JSONP 接口的具體代碼



    4.6.5 在網頁中使用 jQuery 發起 JSONP 請求

    調用 $ajax() 函數, 提供 JSONP 的配置選項 ,從而發起 JSONP 請求,示例代碼如下:


    <<< 第三部分(完)


    上一篇:Node.js 入門詳解 (二)


    下一篇:Node.js 入門詳解 (四)

    總結

    以上是生活随笔為你收集整理的Node.js 入门详解 (三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。