1.hello world
1.1.安裝express
1.進(jìn)入到自己的項(xiàng)目目錄, 我這里是express-demo
cd express-demo
2.初始化項(xiàng)目,生成package.json文件
npm init -y
3.安裝express
npm install express --save
1.2.簡(jiǎn)單使用
在當(dāng)前項(xiàng)目下新建app.js文件
// app.js內(nèi)容
// 引入express
var express = require('express')
var app = express()
app.get('/hi', function (req, res, next){
res.send('hello world!!!')
})
app.listen(8090, function (error) {
console.log('listening on 8090')
})
1.3.自動(dòng)監(jiān)聽(tīng)文件,并且重啟
安裝,可以全局安裝也可以局部安裝
npm install -g nodemon
使用nodemon監(jiān)聽(tīng)文件變化,自動(dòng)重啟服務(wù)
nodemon app.js
2.請(qǐng)求和響應(yīng)
2.1.請(qǐng)求相關(guān)
2.1.1.返回一個(gè)html頁(yè)面
app.get('/', function (req, res){
res.sendFile(path.resolve('./views/index.html'))
})
注意path模塊需要先引入
path模塊可以把一個(gè)路徑解析成一個(gè)對(duì)象,對(duì)象中包含了很多屬性。
2.1.2.接收前臺(tái)get方式發(fā)送過(guò)來(lái)的數(shù)據(jù)
// get方式發(fā)送過(guò)來(lái)的數(shù)據(jù) 使用req.query接收
app.get('/getuser', function (req, res) {
console.log(req.query.userid)
})
// 完整代碼
// 引入express
var express = require('express')
var path = require('path')
var app = express()
var userArr = [
{"id": 1, "name": "xiaoqiang", "age": 18},
{"id": 2, "name": "xiaoli", "age": 19},
{"id": 3, "name": "xiaowang", "age": 20},
{"id": 4, "name": "xiaozhang", "age": 21}
]
app.get('/', function (req, res){
res.sendFile(path.resolve('./views/index.html'))
})
app.get('/user', function (req, res) {
res.sendFile(path.resolve('./views/login.html'))
})
app.get('/getuser', function (req, res) {
res.send(userArr.filter(function (item) {
console.log(item.id, req.query.userid)
return item.id == req.query.userid
}))
})
app.listen(8090, function (error) {
console.log('listening on 8090')
})
2.1.3.接收前臺(tái)post方式發(fā)送過(guò)來(lái)的數(shù)據(jù)
接收post數(shù)據(jù),我們可以使用一個(gè)叫做body-parser的模塊來(lái)幫我們完成
1.第一步,先安裝這個(gè)模塊
npm install body-parser --save
2.第二步,引入這個(gè)模塊,并且作為插件使用
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded({extend: false}))
3.第三步,獲取數(shù)據(jù)
app.post('/login', function (req, res) {
res.send(req.body.user)
})
2.1.4.文件上傳
文件上傳需要用到multer插件,先安裝multer
npm install multer --save
接下來(lái)需要引入multer
var multer = require('multer')
配置multer
var upload = multer({dest: './upload'})
dest 表示 設(shè)置上傳文件目錄
會(huì)在當(dāng)前目錄下自動(dòng)生成一個(gè)upload文件夾,用來(lái)存放上傳的文件
接下來(lái)我們?cè)谑褂眠@個(gè)multer的時(shí)候不能用app.use,因?yàn)槿绻怯胊pp.use的方式使用的話,會(huì)多次觸發(fā),而我們只希望在對(duì)應(yīng)的請(qǐng)求處理的時(shí)候進(jìn)行使用。
- 單文件上傳
app.post('/upload', upload.single('fl'), function (req, res) {
res.send(req.file)
})
處理文件上傳請(qǐng)求
f1是指的文件上傳的input的name
- 多文件上傳
app.post('/upload', upload.array('fl', 3), function (req, res) {
res.send(req.files)
})
- 自定義文件路徑和文件名
node里面一般帶有sync的都象征著是同步方法
var fs = require('fs')
// 檢查目錄是否存在,不存在就創(chuàng)建,如果存在,就直接使用
var createFolder = function(folder) {
try {
//accessSync如果沒(méi)有檢測(cè)到,就會(huì)報(bào)錯(cuò)
//如果報(bào)錯(cuò)了,就會(huì)被catchh抓獲
fs.accessSync(folder)
} catch (e) {
fs.mkdirSync(folder)
//異步方法通常都是需要用到回調(diào)函數(shù)的,所以這里我們要用同步方法,
//也就是要加上sync
}
}
//設(shè)置好路徑和文件名
var uploadFolder = './upload'
// 先創(chuàng)建好上傳目錄
createFolder(uploadFolder)
//去自定義文件上傳后的路徑和自定義文件名字
var storage = multer.diskStorage({
//cb就是callback的縮寫(xiě),回調(diào)函數(shù)
destination: function (req, file, cb) {
//下面這行代碼的意思:有文件就按照uploadFolder進(jìn)行上傳就行了
cb(null, uploadFolder)
},
filename: function (req, file, cb) {
//cb(null,file.originalname) --->這樣傳的話,文件原來(lái)是什么名字,上傳之后就還是什么名字
cb(null, file.fieldname + '-' + new Date().getTime() + path.extname(file.originalname))
}
})
//第一個(gè)storage就是storage定義,第二個(gè)storage是我們定義的上面的那幾行代碼
var upload = multer({storage: storage})
app.post('/upload', upload.array('fl', 3), function (req, res) {
res.send(req.files)
})
2.2.響應(yīng)相關(guān)
2.2.1.send方法
send方法可以返回多種類(lèi)型數(shù)據(jù)
// 返回一個(gè)對(duì)象
res.send({"name":"老張", age: 48})
// 返回?cái)?shù)組
// res.send([1, 2, 3])
// 報(bào)錯(cuò)
// res.write({"name": "xiaoqiang"})
// res.end()
2.2.2.sendStatus
返回狀態(tài)碼
res.sendHeader(404)
如果沒(méi)有這個(gè)方法,你會(huì)這樣寫(xiě):
res.writeHead(404, {'Content-Type': 'text/plain'})
res.write("not found!!!!")
res.end()
很明顯第一種寫(xiě)法更簡(jiǎn)潔。
2.2.3.redirect
redirect用于重定向
app.get('/re', function (req, res) {
res.redirect('http://nodeing.com')
})
如果不使用redirect,而使用原生的語(yǔ)法,需要這樣寫(xiě):
res.setHeader('location', 'http://nodeing.com')
res.writeHead(301)
res.end()
- 301 永久重定向 瀏覽器會(huì)記住
- a.com b.com
- a 瀏覽器不會(huì)請(qǐng)求 a 了
- 直接去跳到 b 了
- 通過(guò)看status code,可以發(fā)現(xiàn)后面寫(xiě)著from cache
- 302 臨時(shí)重定向 瀏覽器不記憶
- a.com b.com
- a.com 還會(huì)請(qǐng)求 a
- a 告訴瀏覽器你往 b
3.路由
路由到底是什么呢?不管官方定義到底是什么,咱通俗的說(shuō)就是根據(jù)不同的url,執(zhí)行不同的代碼,類(lèi)似于編程語(yǔ)言中的分支結(jié)構(gòu)
3.1.express規(guī)劃路由
稍微復(fù)雜點(diǎn)的應(yīng)用,通常都是分模塊進(jìn)行的
我們從中挑選幾個(gè)模塊進(jìn)行路由規(guī)劃,在我們的后臺(tái)模塊里面,可以實(shí)現(xiàn)用戶的管理,課程的管理,友情鏈接管理等,我們的訪問(wèn)地址可能是這樣的
// 1.用戶管理
// 用戶列表
http://localhost:8090/admin/user/list
// 添加用戶
http://localhost:8090/admin/user/add
// 刪除用戶
http://localhost:8090/admin/user/delete
// 編輯用戶
http://localhost:8090/admin/user/edit
// 2.課程管理
// 課程列表
http://localhost:8090/admin/course/list
// 添加用戶
http://localhost:8090/admin/course/add
// 刪除用戶
http://localhost:8090/admin/course/delete
// 編輯用戶
http://localhost:8090/admin/course/edit
...
在沒(méi)有拆分路由的情況下,我們需要在app.js里面寫(xiě)這些代碼
/**
* 用戶管理模塊
*/
app.get('/admin/user/list', function (req, res) {
res.send('用戶列表')
})
app.get('/admin/user/add', function (req, res) {
res.send('添加用戶')
})
app.get('/admin/user/delete', function (req, res) {
res.send('刪除用戶')
})
app.get('/admin/user/edit', function (req, res) {
res.send('更新用戶')
})
/**
* 課程模塊
*/
app.get('/admin/course/list', function (req, res) {
res.send('課程列表')
})
app.get('/admin/course/add', function (req, res) {
res.send('添加課程')
})
app.get('/admin/course/delete', function (req, res) {
res.send('刪除課程')
})
app.get('/admin/course/edit', function (req, res) {
res.send('更新課程')
})
當(dāng)上面的代碼都寫(xiě)到app.js中,代碼會(huì)顯得非常臃腫,最佳的實(shí)踐是把這些模塊拆分出去,express中提供了拆分的方法
第一步,我們?cè)陧?xiàng)目根目錄下面,新建一個(gè)router目錄,在這個(gè)目錄下面按模塊名字分別創(chuàng)建user.js和course.js
第二步,在user.js文件中,創(chuàng)建router,并導(dǎo)出
var express = require('express')
var router = express.Router()
// ... 中間寫(xiě)對(duì)應(yīng)的路由方法
module.exports = router
第三步,把對(duì)應(yīng)的路由方法添加到user.js中
var express = require('express')
var router = express.Router()
router.get('/admin/user/list', function (req, res) {
res.send('用戶列表')
})
router.get('/admin/user/add', function (req, res) {
res.send('添加用戶')
})
router.get('/admin/user/delete', function (req, res) {
res.send('刪除用戶')
})
router.get('/admin/user/edit', function (req, res) {
res.send('更新用戶')
})
module.exports = router
經(jīng)過(guò)前面步驟,我們完成了user模塊路由拆分
接下來(lái),我們可以按照這種方式,把course模塊拆分出來(lái)
// course.js文件代碼
var express = require('express')
var router = express.Router()
router.get('/admin/course/list', function (req, res) {
res.send('課程列表')
})
router.get('/admin/course/add', function (req, res) {
res.send('添加課程')
})
router.get('/admin/course/delete', function (req, res) {
res.send('刪除課程')
})
router.get('/admin/course/edit', function (req, res) {
res.send('更新課程')
})
module.exports = router
當(dāng)我們各個(gè)路由模塊都拆分完成后,如何使用這些模塊呢?
在app.js中,我們需要引入創(chuàng)建好的路由模塊
var userRouter = require('./router/user')
var courseRouter = require('./router/course')
接下來(lái),掛載到express上
app.use('/', userRouter)
app.use('/', courseRouter)
經(jīng)過(guò)以上步驟,我們已經(jīng)把路由模塊完全拆分出去了
3.2.對(duì)路由模塊進(jìn)行多級(jí)拆分
前面我們已經(jīng)把模塊劃分出來(lái)了,我們?cè)趯?xiě)路由方法的時(shí)候是這樣的:
router.get('/admin/user/list', function (req, res) {
res.send('用戶列表')
})
從代碼中我們可以看成,寫(xiě)路徑的時(shí)候會(huì)寫(xiě)一長(zhǎng)串,/admin/user/list,這樣寫(xiě)比較麻煩,同時(shí),我們更希望大模塊直接有更好的劃分,例如,我們的系統(tǒng)總體上劃分為前臺(tái)模塊和后臺(tái)模塊,那我們的router文件夾中應(yīng)該再分home和admin兩個(gè)文件夾
admin文件夾下面放的都是關(guān)于后臺(tái)路由的模塊,home目錄下面放的都是前臺(tái)路由的模塊,這個(gè)時(shí)候,我們需要對(duì)路由做進(jìn)一步拆分,以拆分admin為例:
第一步:在admin/index.js下面 引入其他admin下面的模塊,把其他admin下面的模塊都掛在index.js這個(gè)模塊上然后導(dǎo)出
var express = require('express')
var router = express.Router()
var course = require('./course')
var user = require('./user')
// 掛載user模塊
router.use('/', user)
// 掛載course模塊
router.use('/', course)
module.exports = router
第二步:在app.js中引入admin模塊
//這里的index.js可以不寫(xiě).js,瀏覽器加載時(shí)會(huì)自動(dòng)加上后綴
var adminRouter = require('./router/admin/index')
第三步:把a(bǔ)dminRouter掛到app對(duì)象上
//如果我們請(qǐng)求/admin的話,會(huì)自動(dòng)去找到adminRouter模塊
app.use('/admin', adminRouter)
第四步:需要注意,user.js模塊中的請(qǐng)求路徑需要改變,例如:原來(lái)的"/admin/user/list"這種寫(xiě)法,需要改成這種"/user/list"
3.3.動(dòng)態(tài)路由
動(dòng)態(tài)路由就是路由是動(dòng)態(tài)不固定的,例如:
http;//localhost:8090/user/1
http;//localhost:8090/user/2
http;//localhost:8090/user/3
上面的幾個(gè)url中,都是去訪問(wèn)某個(gè)user,前面部分(http;//localhost:8090/user)是相同的,不同的就是后面的部分
在后臺(tái)我們?cè)趺慈ケO(jiān)聽(tīng)這種形式的url呢?我們可以弄一個(gè)變量來(lái)匹配這些不同的部分,例如:
app.get('/user/:id', function (req, res) {
console.log(req.params)
})
這其中的id就存儲(chǔ)了url中變化的部分
/user/1 id: 1
/user/2 id: 2
/user/3 id: 3
可以通過(guò)req.params.id打印出每次請(qǐng)求的動(dòng)態(tài)部分(動(dòng)態(tài)參數(shù))
4.靜態(tài)文件
4.1.普通處理靜態(tài)文件的方法
在./views/index.html文件中去引入另一個(gè)css文件index.css,index.css文件放在public/css目錄下。
index.html文件中的內(nèi)容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#wrap {
width: 300px;
margin: 100px auto;
line-height: 150px;
height: 150px;
text-align: center;
background-color: green;
}
#wrap a {
color: white;
text-decoration: none;
}
</style>
<link rel="stylesheet" href="/public/css/index.css">
</head>
<body>
<div id="wrap">
<a href="/login">登錄 | </a>
<a href="/user">用戶中心</a>
</div>
</body>
</html>
根據(jù)請(qǐng)求渲染出index.html文件
app.get('/', function (req, res) {
res.sendFile('./index.html')
})
當(dāng)我們方法 '/'這個(gè)路徑的時(shí)候,能把index.html頁(yè)面加載出來(lái),但是沒(méi)辦法把css文件加載出來(lái)
為了解決這個(gè)問(wèn)題,我們還需要單獨(dú)去寫(xiě)一個(gè)路由去返回css文件
app.get('/public/css/index.css', function (req, res) {
res.sendFile(path.resolve('./public/css/index.css'))
})
4.2.express中處理靜態(tài)文件的插件
express中提供了處理靜態(tài)文件的插件,這里的靜態(tài)文件就是我們項(xiàng)目中需要用到的img、css、js等資源,只需要簡(jiǎn)單的配置就可以實(shí)現(xiàn)對(duì)靜態(tài)文件的處理,步驟如下:
第一步,在app中掛載插件
app.use(express.static('./public'))
第二步,使用靜態(tài)文件,在index.html文件中引入css,路徑需要修改一下
<link rel="stylesheet" href="/css/index.css">
5.ejs模版
5.1.什么是模版引擎?
為了使用戶界面與業(yè)務(wù)數(shù)據(jù)(內(nèi)容)分離而產(chǎn)生的,它可以生成特定格式的文檔,用于網(wǎng)站的模板引擎就會(huì)生成一個(gè)標(biāo)準(zhǔn)的HTML文檔。
在后端開(kāi)發(fā)中,處理數(shù)據(jù)的代碼和展示數(shù)據(jù)的代碼是分離的,這就是前面說(shuō)的,用戶界面和業(yè)務(wù)數(shù)據(jù)內(nèi)容分離,但是真的展現(xiàn)到前端給用戶看到的界面都是數(shù)據(jù)和界面融合在一起的,模版引擎的作用就是把html文件和后端的數(shù)據(jù)柔和在一起生成一個(gè)html文件返回給前端展示,這種方式又叫做服務(wù)端渲染。
模板引擎在服務(wù)端所傳遞的變量,只會(huì)在前端的html中執(zhí)行,并且只認(rèn)識(shí)自己的特定符號(hào),js代碼不會(huì)執(zhí)行模板引擎,js會(huì)直接放給瀏覽器執(zhí)行。
5.2.在express中使用ejs模版引擎
第一步,安裝ejs
npm install ejs --save
第二步,在app.js中引入ejs
var ejs = require('ejs')
第三步,設(shè)置express的模版文件夾,app.set方法,表示設(shè)置某個(gè)屬性名的value,例如:設(shè)置express的views,views指express中模版文件的路徑,路徑的值為第二個(gè)參數(shù)給的值
app.set('views', path.join(__dirname, 'views'))
第四步,告訴express使用ejs來(lái)作為模板引擎,并且設(shè)置模板文件后綴
app.engine('html', ejs.__express)
第五步,注冊(cè)模板引擎
app.set('view engine', 'html')
第六步,ejs模板引擎初體驗(yàn)
1.在"/"路由中,渲染"index.html"文件,并帶參數(shù)
app.get('/', function (req, res){
// res.sendFile(path.resolve('./views/index.html'))
res.render('index.html', {title: '螺釘課堂?。?!'})
})
2.在‘index.html’文件中去使用數(shù)據(jù)
<h1><%= title %></h1>
5.3.ejs的常用語(yǔ)法
1.基本語(yǔ)法,后臺(tái)數(shù)據(jù)是融和在html模板中的,在html模板中,通過(guò)自定義標(biāo)簽的形式來(lái)區(qū)分到底是ejs的標(biāo)簽還是html的標(biāo)簽 例如:
<%= title %>
常用的標(biāo)簽:
1、<% if|for %> 這種叫做腳本標(biāo)簽,用于寫(xiě)流程控制
2、<%= 變量 %> 這種標(biāo)簽的作用是把數(shù)據(jù)輸出到html
3、<%- %>這種標(biāo)簽的作用和<%= %>相同,區(qū)別是這種標(biāo)簽可以解析html,<%= %>這種標(biāo)簽會(huì)把html標(biāo)簽給轉(zhuǎn)義了
2.流程控制語(yǔ)句
- if 語(yǔ)句
// 1.后臺(tái)傳入一個(gè) isLogin字段
app.get('/', function (req, res){
// res.sendFile(path.resolve('./views/index.html'))
res.render('index.html', {title: '螺釘課堂?。?!', isLogin: false})
})
// 2.在模板中使用這個(gè)isLogin字段來(lái)做判斷
<% if (isLogin) { %>
<div id="wrap">
<a href="/login">歡迎admin,登錄?。?!</a>
<a href="/user">用戶中心</a>
</div>
<% } else { %>
<div id="wrap">
<a href="/login">登錄 | </a>
<a href="/user">用戶中心</a>
</div>
<% } %>
- for循環(huán)渲染
// 1.在后臺(tái)傳入一個(gè)數(shù)組
app.get('/', function (req, res){
// res.sendFile(path.resolve('./views/index.html'))
var userList = [
{name: '張飛', age: 29},
{name: '關(guān)羽', age: 30},
{name: '劉備', age: 31},
]
res.render('index.html', {title: '螺釘課堂!?。?, isLogin: false, userList: userList})
})
// 2.在模板中循環(huán)出這個(gè)數(shù)組
<ul>
<% for (var i = 0; i < userList.length; i++) {%>
<li><%= userList[i].name %> ----> <%= userList[i].age %></li>
<% } %>
</ul>
// 3.也可以使用forEach方法來(lái)循環(huán)
<ul>
<% userList.forEach(function (item){%>
<li><%= item.name %> ----> <%= item.age%></li>
<% }) %>
</ul>
5.中間件
中間件可以理解為過(guò)濾器,我們通過(guò)一個(gè)自定義的body中間件來(lái)闡述到底什么是中間件?
中間件本質(zhì)上是一個(gè)函數(shù)
中間件都會(huì)有一個(gè)next參數(shù),讓過(guò)濾器能夠一層一層往下執(zhí)行。
中間件需要在路由之前執(zhí)行。
中間件配置必須放在router掛載的前面
在項(xiàng)目根目錄下面創(chuàng)建一個(gè)libs文件夾,然后創(chuàng)建body.js文件
body.js內(nèi)容
const queryString = require('querystring')
function body(req, res, next) {
let arr = []
req.on('data', (chunk, err) => {
if (!err) {
arr.push(chunk)
}
})
req.on('end', (err) => {
//arr沒(méi)處理之前是一個(gè)二進(jìn)制對(duì)象
//用Buffer.concat把a(bǔ)rr數(shù)組里的二進(jìn)制對(duì)象都給連接起來(lái)
//.toString()把前面整個(gè)轉(zhuǎn)換成字符串
//queryString.parse把字符串解析成對(duì)象
req.body = queryString.parse(Buffer.concat(arr).toString())
next()
})
}
module.exports = body
在express中使用body中間件
const express = require('express')
const app = express()
const body = require('./libs/body.js')
app.use(body)
app.post('/user', function(req, res) {
console.log(req.body)
})
app.listen(4001)
中間件:處理請(qǐng)求的,本質(zhì)就是個(gè)函數(shù)
在 Express 中,對(duì)中間件有幾種分類(lèi)
當(dāng)請(qǐng)求進(jìn)來(lái),會(huì)從第一個(gè)中間件開(kāi)始進(jìn)行匹配
如果匹配,則進(jìn)來(lái)
如果請(qǐng)求進(jìn)入中間件之后,沒(méi)有調(diào)用 next 則代碼會(huì)停在當(dāng)前中間件
如果調(diào)用了 next 則繼續(xù)向后找到第一個(gè)匹配的中間件
如果不匹配,則繼續(xù)判斷匹配下一個(gè)中間件
不關(guān)心請(qǐng)求路徑和請(qǐng)求方法的中間件
也就是說(shuō)任何請(qǐng)求都會(huì)進(jìn)入這個(gè)中間件
中間件本身是一個(gè)方法,該方法接收三個(gè)參數(shù):
Request 請(qǐng)求對(duì)象
Response 響應(yīng)對(duì)象
next 下一個(gè)中間件
當(dāng)一個(gè)請(qǐng)求進(jìn)入一個(gè)中間件之后,如果不調(diào)用 next 則會(huì)停留在當(dāng)前中間件
所以 next 是一個(gè)方法,用來(lái)調(diào)用下一個(gè)中間件的
調(diào)用 next 方法也是要匹配的(不是調(diào)用緊挨著的那個(gè))
如果調(diào)用next方法的時(shí)候,傳err參數(shù),則會(huì)將錯(cuò)誤統(tǒng)一匹配給錯(cuò)誤處理中間件,也就是帶有四個(gè)參數(shù)的應(yīng)用程序級(jí)別的中間件。
app.use(function (err, req, res, next) {
res.status(500).send(err.message)
})
應(yīng)用程序級(jí)別中間件
萬(wàn)能匹配(不關(guān)心任何請(qǐng)求路徑和請(qǐng)求方法)
app.use( function (req, res , next){
console.log('Time:',Date.now())
next()
})
只要是以’/xxx/‘開(kāi)頭的
app.use ('/a',function (req,res,next){
console.log('Time:',Date.now())
next()
})
路徑級(jí)別中間件
get:
app.get ('/',function (req,res){
res.end('Hello World!')
})
post:
app.post('/',function (req,res){
res.end('Got a POST request')
})
put:
app.put( '/user',function (req,res){
res.send ('Got a PUT request at /user')
})
express解決跨域問(wèn)題
方式一:
不用中間件的話可以這樣寫(xiě)
const express = require('express')
const app = express()
app.use((req, res, next) => {
// 設(shè)置是否運(yùn)行客戶端設(shè)置 withCredentials
// 即在不同域名下發(fā)出的請(qǐng)求也可以攜帶 cookie
res.header("Access-Control-Allow-Credentials",true)
// 第二個(gè)參數(shù)表示允許跨域的域名,* 代表所有域名
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS') // 允許的 http 請(qǐng)求的方法
// 允許前臺(tái)獲得的除 Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma 這幾張基本響應(yīng)頭之外的響應(yīng)頭
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With')
if (req.method == 'OPTIONS') {
res.sendStatus(200)
} else {
next()
}
})
方式二:
使用CORS,和其他中間件的用法一樣,app.use()即可:
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
如果要單獨(dú)為某個(gè)接口實(shí)現(xiàn)允許跨域請(qǐng)求,在回調(diào)函數(shù)之前先用cors()方法進(jìn)行跨域處理即可:
var express = require('express')
var cors = require('cors')
var app = express()
app.get('/products/:id', cors(), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for a Single Route'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})
還可以自己手動(dòng)配置:
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})