教程系列之二:前端全栈node的CORS跨域,文件上传,路由和cookie,session

上篇文章讲了vue项目使用服务器代理完成跨域,此次说一个服务端来完成这个跨域工做,就是cors跨域。javascript

CORS背后的基本思想是使用自定义的HTTP头部容许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。

其实这个自从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;
复制代码

若是你要上传多个文件能够将上面的upload.single改成upliad.array('文件名', 数量)

客户端代码,这里要注意当你使用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

讲道理,cookie和session是服务端和客户端通讯的重要保障。

由于互联网上的东西彼此之间根本不认识,http就是无状态请求,只能经过相似于暗号同样的东西来肯定对方是否可信。而cookie和session就至关于这个暗号。 说下cookie和sesiion究竟是什么:axios

cookie:它存储在客户端,也就是浏览器,但每次向服务端发起请求时都会带上cookie做为用户的凭证。

注意:任何放在客户端的东西都是不安全的,cookie也是,它很容易被篡改,因此通常重要信息都不会放在cookie。并且,它有大小的限制,通常只有4k。固然,为了防篡改,cookie有一个签名机制。

session:存储在服务器,不是独立存在的,通常基于cookie,就是在cookie里会保存一个id用来在服务端作验证,固然也能够用别的第三方验证

由于session是存储在服务端,相对会安全不少,并且理论上没有大小的限制。

接下来说下怎么在express中使用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中间件,我记得有的面试官会问能不能手写中间件,其实也没什么难的。

最后说下session

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的使用。

相关文章
相关标签/搜索