上篇文章講了vue項目使用服務器代理完成跨域,此次說一個服務端來完成這個跨域工做,就是cors跨域。javascript
其實這個自從ajax2.0就支持了。這裏咱們講下node是怎麼來配置這個cors跨域的這裏仍是以express框架爲例,這個相對koa比較好理解點,後面會講koa。vue
```javascript
//當你使用的是常規的跨域請求,只要設置,響應頭
app.use((req, res) => {
res.header('Access-Control-Allow-Origin','*');//設置跨域須要的響應頭。
})
```
複製代碼
上面是對全部的請求都贊成跨域,固然,若是考慮安全,你也能夠根據本身的須要,先對請求作一個驗證,再決定是否加這個響應頭,好比java
```javascript
app.use((req, res, next) => {
if(req.headers['origin'] && url.parse(req.headers['origin']).hostname == 'localhost'){
res.header('Access-Control-Allow-Origin','*');//自定義中間件,設置跨域須要的響應頭。
}else{
next()
}
})
```
複製代碼
針對普通的跨域請求只要加個響應頭便可,若是是特殊的請求,好比put,delete,或者你在請求頭裏定義了一些本身的東西,這時你就要設置服務端相應的Access-Control-Allow-Methods和Access-Control-Allow-Headers,這個根據本身的狀況來加就能夠了node
是否是一會兒感受cors跨域原來這麼簡單。ios
在express框架裏,若是要上傳文件須要依賴一箇中間件multer,固然也能夠是別的中間件,這裏以multer爲例。 服務端代碼面試
const express = require('express')
const router = express.Router()
const multer = require('multer') //express框架上傳文件所須要的中間件
var upload = multer({ //multer中間件的使用方法能夠命令行npm search multer
dest: './uploads/' //決定文件上傳存放的目錄
})
router.post('/upload', upload.single('avatar'), (req, res) => { //注意這裏的avatar
var fileName = "";
console.log(req.file);
if (req.file != undefined) {
fileName = new Date().getTime() + "_" + req.file.originalname;
fs.rename(req.file.path, __dirname + "/" + fileName, err => {
if(err) console.log(err)
}); //重命名,加後綴,否則圖片會顯示亂碼,打不開
}
res.send("1");
})
module.exports = router;
複製代碼
客戶端代碼,這裏要注意當你使用formData來append你的文件的時候,必定要保證文件名和服務端要接受的文件名一致。ajax
uploadImg () {
let formData = new FormData();
formData.append('avatar', this.file) //注意,這裏必須上傳文件的name爲avatar要和服務端接收的保持一致
this.$axios.post('/api/admin/upload', formData)
複製代碼
一個大點的項目會有不少請求路徑,每一個路徑下面還會細分,這時路由的做用就體現出來了。 在express中,它自己就帶有路由模塊,這裏咱們來簡單的演示下express
//server.js
const express = require('express')
const bodyParser = require('body-parser')
let app = express()
app.listen(8080)
app.use(bodyParser.urlencoded({
extended: false
}))
app.use('/user', require('./routers/user')) //當收到/user請求時會去找對應的user文件
app.use('/news', require('./routers/news'))
//當收到/user請求時會去找對應的news文件
//user.js,news.js也與其相似
const express = require('express')
const router = express.Router()
module.exports = router
router.get('/login', (req,res) => {})
複製代碼
這樣一來,咱們就把每一個請求都分離出去,讓server.js看起來很清爽。npm
由於互聯網上的東西彼此之間根本不認識,http就是無狀態請求,只能經過相似於暗號同樣的東西來肯定對方是否可信。而cookie和session就至關於這個暗號。 說下cookie和sesiion究竟是什麼:axios
注意:任何放在客戶端的東西都是不安全的,cookie也是,它很容易被篡改,因此通常重要信息都不會放在cookie。並且,它有大小的限制,通常只有4k。固然,爲了防篡改,cookie有一個簽名機制。
由於session是存儲在服務端,相對會安全不少,並且理論上沒有大小的限制。
使用cookie須要中間件cookie-parser,直接cnpm i cookie-parser
const cookieParser=require("cookie-parser");
app.use(cookieParser('secret'));
//註冊登錄post 方法;
Router.post("/login",function (req,res) {
const {userid}=req.cookies; //讀取瀏覽器傳過來的cookie
res.cookie("userid",'chyingp', {'本身設置參數'}) //設置響應頭的cookie
複製代碼
能夠在響應頭裏設置: maxAge存活時間,domain域名,path路徑, httpOnly是否只讓服務端操做, secure是否只用在https 還有一個signed,這個就是是否簽名,當爲true就要簽名。
res.cookie('userid', 'chyingp', {signed: true});
複製代碼
這樣配合上面的cookieParser就完成一個簽名,下面講下cookieParser是怎麼實現這個簽名的
res.cookie = (name, value, options) => {
var secret = this.req.secret;
var signed = opts.signed;
// 若是 options.signed 爲true,則對cookie進行簽名
if (signed) {
val = 's:' + sign(val, secret);
}
this.append('Set-Cookie', cookie.serialize(name, String(val), opts));
return this;
};
複製代碼
裏面的sign函數實現:
function sign (val, secret) {
return val + '.' + hmac(val, secret); //hmac是一種密鑰碼
}
複製代碼
到這裏,咱們就實現了一個簡單版的cookie-parser中間件,我記得有的面試官會問能不能手寫中間件,其實也沒什麼難的。
express用session須要cookie-session中間件 示例代碼:
const cookieSession = require('cookie-session');
app.use(cookieSession({
//會話在cookie中的名稱
name: 'session',
//用於簽名的密鑰
keys: ['j239r5ndgffhfghhgjhyyw45646fte'],
//cookie過時時間,單位毫秒
maxAge: 3600 * 1000
}));
//使用
app.get('/', function (req, res) {
//獲取會話數據
console.log(req.session);
//設置會話數據
req.session.name = 'zhangsan';
res.end();
});
複製代碼
到這裏,其實已經可使用node進行簡單的開發了,有接口,有路由,有文件上傳,有cookie,session。起碼用來作一個本身的我的博客是ok的。 後面,就不講express了,在大型項目中,你們其實都更傾向於koa,由於express是基於回調的,容易死於回調。。。最新的koa是基於async await的,用起來更爽,後面我會分享一些koa的使用。