NodeJs Express框架實現(xiàn)服務(wù)器接口詳解
創(chuàng)建基本的服務(wù)器
創(chuàng)建 API 路由模塊
編寫 GET 接口
編寫 POST 接口
注意:如果要獲取 URL-encoded 格式的請求體數(shù)據(jù),必須配置中間件 app.use(express.urlencoded({ extended: false }))
CORS 跨域資源共享
1. 接口的跨域問題
<body> <button id="btnGET">GET</button> <button id="btnPOST">POST</button> <button id="btnDelete">DELETE</button> <button id="btnJSONP">JSONP</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) }, }) }) // 3. 為刪除按鈕綁定點擊事件處理函數(shù) $('#btnDelete').on('click', function () { $.ajax({ type: 'DELETE', url: 'http://127.0.0.1/api/delete', success: function (res) { console.log(res) }, }) }) // 4. 為 JSONP 按鈕綁定點擊事件處理函數(shù) $('#btnJSONP').on('click', function () { $.ajax({ type: 'GET', url: 'http://127.0.0.1/api/jsonp', dataType: 'jsonp', success: function (res) { console.log(res) }, }) }) }) </script> </body>
剛才編寫的 GET 和 POST接口,存在一個很嚴重的問題:不支持跨域請求。
解決接口跨域問題的方案主要有兩種:
① CORS(主流的解決方案,推薦使用)
② JSONP(有缺陷的解決方案:只支持 GET 請求)
2. 使用 cors 中間件解決跨域問題
cors 是 Express 的一個第三方中間件。通過安裝和配置 cors 中間件,可以很方便地解決跨域問題。
使用步驟分為如下 3 步:
① 運行 npm install cors 安裝中間件
② 使用 const cors = require(‘cors’) 導(dǎo)入中間件
③ 在路由之前調(diào)用 app.use(cors()) 配置中間件
// 導(dǎo)入 express const express = require('express') // 創(chuàng)建服務(wù)器實例 const app = express() // 配置解析表單數(shù)據(jù)的中間件 app.use(express.urlencoded({ extended: false })) // 必須在配置 cors 中間件之前,配置 JSONP 的接口 app.get('/api/jsonp', (req, res) => { // TODO: 定義 JSONP 接口具體的實現(xiàn)過程 // 1. 得到函數(shù)的名稱 const funcName = req.query.callback // 2. 定義要發(fā)送到客戶端的數(shù)據(jù)對象 const data = { name: 'zs', age: 22 } // 3. 拼接出一個函數(shù)的調(diào)用 const scriptStr = `${funcName}(${JSON.stringify(data)})` // 4. 把拼接的字符串,響應(yīng)給客戶端 res.send(scriptStr) }) // 一定要在路由之前,配置 cors 這個中間件,從而解決接口跨域的問題 const cors = require('cors') app.use(cors()) // 導(dǎo)入路由模塊 const router = require('./16.apiRouter') // 把路由模塊,注冊到 app 上 app.use('/api', router) // 啟動服務(wù)器 app.listen(80, () => { console.log('express server running at http://127.0.0.1') })
//apiRouter.js const express = require('express') const router = express.Router() // 在這里掛載對應(yīng)的路由 router.get('/get', (req, res) => { // 通過 req.query 獲取客戶端通過查詢字符串,發(fā)送到服務(wù)器的數(shù)據(jù) const query = req.query // 調(diào)用 res.send() 方法,向客戶端響應(yīng)處理的結(jié)果 res.send({ status: 0, // 0 表示處理成功,1 表示處理失敗 msg: 'GET 請求成功!', // 狀態(tài)的描述 data: query, // 需要響應(yīng)給客戶端的數(shù)據(jù) }) }) // 定義 POST 接口 router.post('/post', (req, res) => { // 通過 req.body 獲取請求體中包含的 url-encoded 格式的數(shù)據(jù) const body = req.body // 調(diào)用 res.send() 方法,向客戶端響應(yīng)結(jié)果 res.send({ status: 0, msg: 'POST 請求成功!', data: body, }) }) // 定義 DELETE 接口 router.delete('/delete', (req, res) => { res.send({ status: 0, msg: 'DELETE請求成功', }) }) module.exports = router
什么是 CORS
CORS (Cross-Origin Resource Sharing,跨域資源共享)由一系列 HTTP 響應(yīng)頭組成,這些 HTTP 響應(yīng)頭決定
瀏覽器是否阻止前端 JS 代碼跨域獲取資源。
瀏覽器的同源安全策略默認會阻止網(wǎng)頁“跨域”獲取資源。但如果接口服務(wù)器配置了 CORS 相關(guān)的 HTTP 響應(yīng)頭,
就可以解除瀏覽器端的跨域訪問限制。
CORS 的注意事項
① CORS 主要在服務(wù)器端進行配置??蛻舳藶g覽器無須做任何額外的配置,即可請求開啟了 CORS 的接口。
② CORS 在瀏覽器中有兼容性。只有支持 XMLHttpRequest Level2 的瀏覽器,才能正常訪問開啟了 CORS 的服
務(wù)端接口(例如:IE10+、Chrome4+、FireFox3.5+)。
CORS 響應(yīng)頭部 - Access-Control-Allow-Origin
響應(yīng)頭部中可以攜帶一個 Access-Control-Allow-Origin 字段,其語法如下:
其中,origin 參數(shù)的值指定了允許訪問該資源的外域 URL
。
例如,下面的字段值將只允許來自 http://itcast.cn 的請求:
如果指定了 Access-Control-Allow-Origin 字段的值為通配符 *****,表示允許來自任何域的請求,示例代碼如下:
CORS 響應(yīng)頭部 - Access-Control-Allow-Headers
默認情況下,CORS 僅支持客戶端向服務(wù)器發(fā)送如下的 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 三者之一)
如果客戶端向服務(wù)器發(fā)送了額外的請求頭信息,則需要在服務(wù)器端,通過 Access-Control-Allow-Headers 對額外的請求頭進行聲明,否則這次請求會失敗
CORS 響應(yīng)頭部 - Access-Control-Allow-Methods
默認情況下,CORS 僅支持客戶端發(fā)起 GET、POST、HEAD 請求。
如果客戶端希望通過 PUT、DELETE 等方式請求服務(wù)器的資源,則需要在服務(wù)器端,通過 Access-Control-Alow-Methods來指明實際請求所允許使用的 HTTP 方法。
示例代碼如下
CORS請求的分類
客戶端在請求 CORS 接口時,根據(jù)請求方式和請求頭的不同,可以將 CORS 的請求分為兩大類,分別是:
① 簡單請求
② 預(yù)檢請求
簡單請求
同時滿足以下兩大條件的請求,就屬于簡單請求:
① 請求方式: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)
預(yù)檢請求
只要符合以下任何一個條件的請求,都需要進行預(yù)檢請求:
① 請求方式為 GET、POST、HEAD 之外
的請求 Method 類型
② 請求頭中包含自定義頭部字段
③ 向服務(wù)器發(fā)送了 application/json 格式的數(shù)據(jù)
在瀏覽器與服務(wù)器正式通信之前,瀏覽器會先發(fā)送 OPTION 請求進行預(yù)檢,以獲知服務(wù)器是否允許該實際請求,所以這一次的 OPTION 請求稱為“預(yù)檢請求”。服務(wù)器成功響應(yīng)預(yù)檢請求后,才會發(fā)送真正的請求,并且攜帶真實數(shù)據(jù)。
簡單請求和預(yù)檢請求的區(qū)別
簡單請求的特點:客戶端與服務(wù)器之間只會發(fā)生一次請求。
預(yù)檢請求的特點:客戶端與服務(wù)器之間會發(fā)生兩次請求,OPTION 預(yù)檢請求成功之后,才會發(fā)起真正的請求。
回顧 JSONP 的概念與特點
概念:瀏覽器端通過 script標簽的 src 屬性,請求服務(wù)器上的數(shù)據(jù),同時,服務(wù)器返回一個函數(shù)的調(diào)用。這種請求數(shù)據(jù)的方式叫做 JSONP。
特點:
① JSONP 不屬于真正的 Ajax 請求,因為它沒有使用 XMLHttpRequest 這個對象。
② JSONP 僅支持 GET 請求,不支持 POST、PUT、DELETE 等請求。
創(chuàng)建 JSONP 接口的注意事項
如果項目中已經(jīng)配置了 CORS 跨域資源共享,為了防止沖突,必須在配置 CORS 中間件之前聲明 JSONP 的接口。否則JSONP 接口會被處理成開啟了 CORS 的接口。示例代碼如下:
實現(xiàn) JSONP 接口的步驟
① 獲取客戶端發(fā)送過來的回調(diào)函數(shù)的名字
② 得到要通過 JSONP 形式發(fā)送給客戶端的數(shù)據(jù)
③ 根據(jù)前兩步得到的數(shù)據(jù),拼接出一個函數(shù)調(diào)用的字符串
④ 把上一步拼接得到的字符串,響應(yīng)給客戶端的 script標簽進行解析執(zhí)行
實現(xiàn) JSONP 接口的具體代碼
// 必須在配置 cors 中間件之前,配置 JSONP 的接口 app.get('/api/jsonp', (req, res) => { // TODO: 定義 JSONP 接口具體的實現(xiàn)過程 // 1. 得到函數(shù)的名稱 const funcName = req.query.callback // 2. 定義要發(fā)送到客戶端的數(shù)據(jù)對象 const data = { name: 'zs', age: 22 } // 3. 拼接出一個函數(shù)的調(diào)用 const scriptStr = `${funcName}(${JSON.stringify(data)})` // 4. 把拼接的字符串,響應(yīng)給客戶端 res.send(scriptStr) })
在網(wǎng)頁中使用 jQuery 發(fā)起 JSONP 請求
調(diào)用 $.ajax() 函數(shù),提供 JSONP 的配置選項,從而發(fā)起 JSONP 請求,示例代碼如下:
// 為 JSONP 按鈕綁定點擊事件處理函數(shù) $('#btnJSONP').on('click', function () { $.ajax({ type: 'GET', url: 'http://127.0.0.1/api/jsonp', dataType: 'jsonp', success: function (res) { console.log(res) }, }) })
到此這篇關(guān)于NodeJs Express框架實現(xiàn)服務(wù)器接口詳解的文章就介紹到這了,更多相關(guān)NodeJs Express 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
從零學習node.js之利用express搭建簡易論壇(七)
這篇文章主要介紹了node.js利用express搭建簡易論壇的方法,我們需要搭建的這個簡易的論壇主要的功能有:注冊、登錄、發(fā)布主題、回復(fù)主題。下面我們來一步步地講解這個系統(tǒng)是如何實現(xiàn)的,需要的朋友可以參考借鑒。2017-02-02nodejs中內(nèi)置模塊fs,path常見的用法說明
這篇文章主要介紹了nodejs中內(nèi)置模塊fs,path常見的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11Nodejs中怎么實現(xiàn)函數(shù)的串行執(zhí)行
今天小編就為大家分享一篇關(guān)于Nodejs中怎么實現(xiàn)函數(shù)的串行執(zhí)行,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03Ajax獲取node服務(wù)器數(shù)據(jù)的完整步驟
這篇文章主要給大家介紹了關(guān)于Ajax獲取node服務(wù)器數(shù)據(jù)的完整步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09