使用ExpressJS如何检查Content-Type?

36

目前我有一个相当基础的RESTful API,并且我的Express应用程序已配置如下:

app.configure(function () {
  app.use(express.static(__dirname + '/public'));
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
});

app.post('/api/vehicles', vehicles.addVehicle);
我该如何/在哪里添加中间件以阻止请求到达我的app.postapp.get,如果内容类型不是application/json
这个中间件应该只会停止带有不正确Content-Type的请求到一个以/api/开头的URL。
6个回答

61
如果您正在使用Express 4.0或更高版本,您可以在处理程序中调用request.is()以过滤请求内容类型。例如:
app.use('/api/', (req, res, next) => {
    if (!req.is('application/json')) {
        // Send error here
        res.send(400);
    } else {
        // Do logic here
    }
});

31

这将中间件挂载在/api/下(作为前缀),并检查内容类型:

app.use('/api/', function(req, res, next) {
  var contype = req.headers['content-type'];
  if (!contype || contype.indexOf('application/json') !== 0)
    return res.send(400);
  next();
});

2
我认为应该是:contype.indexOf('application/json') !== 1,因为indexOf在未找到时返回-1,0是一个有效的元素且是第一个元素。 - Dado
1
我不确定你的意思,这里的 contype.indexOf() 是在搜索一个字符串并确保它以 'application/json' 开头。如果它不在字符串的开头,那么它就是其他内容类型(甚至可能是像 'foo/x-bar-baz; blah=application/json' 这样的东西)。 - mscdex
啊,我明白了。我原本以为要访问多个内容类型指令,req.headers['content-type'] 会返回一个数组本身,所以你只需要使用 !== -1 搜索该数组中是否有 'application/json' 即可。 - Dado

4
从请求中获取内容类型,请使用此代码。
req.get('Content-Type')

示例:

app.post("/api/test", (req, res) => {
    console.log("Request type :", req.get('Content-Type'));
    //your code
})

只是想添加一下,如果没有设置,它可能会返回 undefined - Mote Zart

1
添加此Express中间件将验证所有PATCH、POST和PUT请求,并确保它们包含application/json头:
app.use((req, res, next) => {
    if (['PATCH', 'POST', 'PUT'].includes(req.method) && !req.is('application/json')) {
        res.send(400);
    } else {
        next();
    }
});

将其限制在某些方法中将防止其他方法(如GET)出现错误


1
作为替代方案,您可以使用express-ensure-ctype中间件:
const express = require('express');
const ensureCtype = require('express-ensure-ctype');

const ensureJson = ensureCtype('json');
const app = express();

app.post('/', ensureJson, function (req, res) {
  res.json(req.body);
});

app.listen(3000);

0

对于输入验证,一个好的模块是express-validator。它提供了所需的中间件来进行任何类型的检查。在您的情况下,可以使用以下内容:

const { check, validationResult } = require('express-validator')
app.use('/api/', [
   check('content-type').equals('application/json')
 ], function(req, res, next) {
   const errors = validationResult(req);
   if (!errors.isEmpty()) {
     return res.status(422).json({ errors: errors.array() });
   }
   next();
});

看起来比 request.is() 更加繁琐。 - JuJoDi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接