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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【node进阶】深度解析express框架---编写接口|解决跨域问题

發布時間:2024/3/24 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【node进阶】深度解析express框架---编写接口|解决跨域问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 作者簡介:一名普通本科大三的學生,致力于提高前端開發能力
? 個人主頁:前端小白在前進的主頁
🔥 系列專欄 : node.js學習專欄
?? 個人社區 : 個人交流社區
🍀 學習格言: ?? 打不倒你的會使你更強!??


🔥前言

我們在做前后端分離項目的時候,我們經常調用后端所給我們的接口,從而獲取接口中的信息,這一篇文章將帶領大家做自己的后端,給大家講解怎么去運用node給自己寫接口,同時幫助大家解決經常遇到的跨域問題

📃目錄

  • 學前先知:req.body | req.query | req.params
    • req.body
    • req.query
    • req.params
  • 使用express編寫接口
  • 跨域問題
    • 什么是跨域
    • 為什么會產生跨域問題
  • 解決跨域的兩種方案
    • 1. CORS 解決跨域
      • 什么是 CORS
      • 使用 cors 中間件解決跨域問題
      • cors的三個響應頭
        • Access-Control-Allow-Origin
        • Access-Control-Allow-Headers
        • Access-Control-Allow-Methods
      • CORS請求的分類
        • 簡單請求
        • 預檢請求
        • 簡單請求與預檢請求的區別
    • 2. jsonp解決跨域
      • jsonp的概念
      • jsonp的原理
      • 創建 JSONP 接口的注意事項
      • 實現jsonp接口的步驟
  • 小結

學前先知:req.body | req.query | req.params

想要從web的后臺中獲取接口的數據,傳參是必不可少的,后臺想要接收前臺傳來的數據需要借助一些內置的方法:

req.body

在express框架中,用req.body接收post客戶端的數據,該屬性主要用于post()方法時傳遞參數使用,用法最廣泛,在你想使用這個方法的時候必須要導入第三方中間件body-parser.

演示代碼:

const express = require('express') const app = express() const body_parser = require('body-parser') app.use(body_parser.urlencoded({extended : false})) app.post('/user',(req,res)=>{console.log(req.body); //[Object: null prototype] { name: 'james', age: '37', gender: '男' }res.send('ok') })app.listen(80,()=>{console.log('http://127.0.0.1'); })

這里使用了postman測試工具,打印出來的req.body為前臺傳給后臺的參數,后臺告訴了前臺接收到了參數,打印了ok


req.query

req.query用來獲取get方法傳遞的參數,在這里就無需載入中間件了。

演示代碼:

const express = require('express');const app = express(); // 測試地址:http://127.0.0.1/user/?name=jamesapp.get('/user', function(req, res){let param = req.query.name; console.log(param) //jamesres.send('ok'); }); app.listen(80,()=>{console.log('http://127.0.0.1'); })

在postman中測試地址為http://127.0.0.1?name=james,通過req.query取到了一個對象{name : 'james'},隨后拿到name屬性即可


req.params

有時候我們遇到的地址欄可能會是這種形式:http://127.0.0.1/user/1,這時候就需要我們的req.params去接收前臺傳來的參數

演示代碼:

const express = require('express') const app = express()app.get('/user/:id', function(req, res){let param = req.params.id; //1console.log(param)res.send('ok'); }); app.listen(80,()=>{console.log('http://127.0.0.1'); })

在postman中自創地址http://127.0.0.1/user/1,通過req.query獲取到一個對象{id:1},隨后取出對象中的屬性即可


使用express編寫接口

  • 創建基本的服務器

    const express = require('express') //創建express實例 const app = express() //在這里寫下你的業務代碼...//調用app.listen 方法,指定端口號并啟動web服務器 app.listen('80',()=>{console.log('http://127.0.0.1'); })
  • 創建api路由模塊

    const express = require('express') const apiRouter = express.Router() //在這里寫下你所創建的路由...//將apiRouter導出為一個模塊 module.exports = apiRouter
  • 將模塊導入創建基本服務的文件中

    const express = require('express')const app = express() const apiRouter = require('./16.apiRouter') app.use('/api',apiRouter) app.listen('80',()=>{console.log('http://127.0.0.1'); })
  • 編寫get接口

    apiRouter.get('/get',(req,res)=>{// 通過 req.query 獲取客戶端通過查詢字符串,發送到服務器的數據const query = req.query// 調用 res.send() 方法,向客戶端響應處理的結果res.send({status : 0, // 0 表示處理成功,1 表示處理失敗msg : 'GET請求成功!', // 狀態的描述data : query // 需要響應給客戶端的數據}) })
  • 編寫post接口

    apiRouter.post('/post',(req,res)=>{// 通過 req.body 獲取請求體中包含的 url-encoded 格式的數據const body = req.body// 調用 res.send() 方法,向客戶端響應結果res.send({status : 0, msg : 'post請求成功!',data : body}) })

    注意:如果要獲取 URL-encoded 格式的請求體數據,須配置中間件:app.use(express.urlencoded({ extended: false }))

  • 編寫delete接口

    // 定義 DELETE 接口 apiRouter.delete('/delete', (req, res) => {res.send({status: 0,msg: 'DELETE請求成功',})})

跨域問題

什么是跨域

我們剛才編寫的接口,存在一個很嚴重的問題:不支持跨域請求。那么什么是跨域(CORS)呢?
當一個請求url的協議、域名、端口號三者之間任意一個與當前頁面url不同即為跨域.
舉個例子:我當前的url為:http://127.0.0.1/user,但是我想訪問url為https://127.0.0.1/admin中的數據,我能訪問的到嗎?顯然是不可能的,這就產生了跨域問題!

為什么會產生跨域問題

出于瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。
可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的javascript腳本和另外一個域的內容進行交互。
所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port)


解決跨域的兩種方案

1. CORS 解決跨域

什么是 CORS

CORS (Cross-Origin Resource Sharing,跨域資源共享)由一系列HTTP 響應頭組成,這些 HTTP 響應頭決定瀏覽器是否阻止前端 JS 代碼跨域獲取資源。
瀏覽器的同源安全策略默認會阻止網頁“跨域”獲取資源。但如果接口服務器配置了 CORS 相關的 HTTP 響應頭,就可以解除瀏覽器端的跨域訪問限制。

上圖中,如果我們網頁對服務器發送了跨域請求,服務器受到請求后返回書記,但是在返回的時候,瀏覽器的同源策略安全機制攔截了響應的數據,這就導致了跨域。

上圖中,使用cors后,配置了響應頭Access-Control-Allow-*,這樣的話解除了瀏覽器對響應的攔截,也就是解除了跨域。

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


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

cors 是 Express 的一個第三方中間件。通過安裝和配置 cors 中間件,可以很方便地解決跨域問題。
使用步驟分為如下 3 步:

  • 運行 npm install cors 安裝中間件
  • 使用 const cors = require('cors') 導入中間件
  • 在路由之前調用 app.use(cors()) 配置中間件
  • 代碼示例:

    const express = require('express')const app = express() app.use(express.urlencoded({extended : false}))//一定要在路由之前,配置cors 這個中間件,從而解決接口跨域問題 const cors = require('cors') app.use(cors()) //將上方的apiRouter模塊導入進來 const apiRouter = require('./16.apiRouter') //訪問加上前綴 app.use('/api',apiRouter) app.listen('80',()=>{console.log('http://127.0.0.1'); })

    cors的三個響應頭

    Access-Control-Allow-Origin

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

    Access-Control-Allow-Origin : <origin> | *

    其中,origin 參數的值指定了允許訪問該資源的外域 URL。
    如果指定了 Access-Control-Allow-Origin 字段的值為通配符 *,表示允許來自任何域的請求。
    例如,下面的兩個字段值將分別允許來自 http://127.0.0.1/user 和任何url的請求:

    //該設置允許來自`http://127.0.0.1/user`的請求 res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1/user')//該設置允許所有的url的請求 res.setHeader('Access-Control-Allow-Origin','*')

    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 對額外的請求頭進行聲明,否則這次請求會失敗!

    res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')

    該設置的目的是:允許客戶端額外向服務器發送 Content-Type 請求頭和X-Custom-Header 請求頭
    注意:多個請求頭之間使用英文逗號隔開進行分割。


    Access-Control-Allow-Methods

    默認情況下,CORS 僅支持客戶端發起 GET、POST、HEAD 請求。
    如果客戶端希望通過 PUT、DELETE 等方式請求服務器的資源,則需要在服務器端,通過 Access-Control-Alow-Methods來指明實際請求所允許使用的 HTTP 方法。

    示例代碼如下:

    //只允許 POST、GET、DELETE、HEAD 請求方法 res.setHeader('Access-Control-Allow-Methods','POST','GET','DELETE','HEAD') //允許所有的HTTP請求方法 res.setHeader('Access-Control-Allow-Methods','*')

    CORS請求的分類

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

    簡單請求

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

  • 請求方式: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)
  • 預檢請求

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

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

    簡單請求與預檢請求的區別

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

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


    2. jsonp解決跨域

    jsonp的概念

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

    注意:

  • JSONP 不屬于真正的 Ajax 請求,因為它沒有使用 XMLHttpRequest 這個對象。
  • JSONP 僅支持 GET 請求(重點!!!),不支持 POST、PUT、DELETE 等請求。
  • JSONP 需要前后端共同協調

  • jsonp的原理

    動態創建script標簽,src屬性指向沒有跨域限制(重點!!!),指向一個接口,接口返回的格式一定是 ****() 函數表達式。


    創建 JSONP 接口的注意事項

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

    // 必須在配置 cors 中間件之前,配置 JSONP 的接口【這個接口不會被處理成cors接口】 app.get('/api/jsonp', (req, res) => {...}) //一定要在路由之前,配置cors 這個中間件,從而解決接口跨域問題【后續的所有接口,都會被處理為 cors接口】 const cors = require('cors') app.use(cors())//在這里開啟了一個 cors 的接口 app.get('api/get',(req,res)=>{...})

    實現jsonp接口的步驟

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

    app.get('/api/jsonp', (req, res) => {// TODO: 定義 JSONP 接口具體的實現過程// 1. 得到函數的名稱const funcName = req.query.callback// 2. 定義要發送到客戶端的數據對象const data = { name: 'zs', age: 22 ,req:req.query}// 3. 拼接出一個函數的調用const scriptStr = `${funcName}(${JSON.stringify(data)})`// 4. 把拼接的字符串,響應給客戶端res.send(scriptStr)})

    隨后在網頁中發送jsonp請求即可,這里用的是$.ajax():

    <button id="btnJSONP">JSONP</button> $('#btnJSONP').on('click', function () {$.ajax({type: 'GET',url: 'http://127.0.0.1/api/jsonp',dataType: 'jsonp',success: function (res) {console.log(res) //{ name: 'zs', age: 20 }},}) })

    小結

    本篇的內容主要就是針對express的接口編寫和解決跨域的,接口的編寫非常的容易上手,現階段并沒有到數據庫銜接,等后續文章更新數據庫之后,就可以真正做一個全棧開發者了,前端中,跨域的問題必須要會,這里提供了最常用的cors解決跨域,jsonp在實際開發中使用較少,還有一種反向代理的方式,如果有機會更新vue的時候會詳細講解反向代理,好了,少年,繼續加油吧!😀😀


    👑書寫不易,希望大家能夠給予三連支持,期待我更好的文章喲👑

    總結

    以上是生活随笔為你收集整理的【node进阶】深度解析express框架---编写接口|解决跨域问题的全部內容,希望文章能夠幫你解決所遇到的問題。

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