我已经尝试了很多方法来查找问题,但没有任何效果。这里有详细信息,包括我的错误(在最后)。我只是将相关代码放在这里。我使用express-validator 7.1.0
我正在尝试验证更大的 html (ejs) 表单:
<%- include('partials/header') %>
<h1>Feature-Request hinzufügen</h1>
<body>
<form class="addrequest" enctype="multipart/form-data" id="new_document_attachment" action="/auth/request/create" method="POST">
<div class="form-group mb-2">
<label for="title">Titel</label>
<input type="text" class="form-control" id="title" name="title" maxlength="50" required>
</div>
<div class="form-group mb-2">
<!-- https://jsfiddle.net/djibe89/knv43w6t/118/ -->
<label for="description">Beschreibung</label>
<textarea class="form-control" id="description" name="description" rows="10" maxlength="<%=MAX_DESCRIPTION_CHARACTER_INPUT%>" required></textarea>
</div>
<div class="mb-2">
<label for="formFile" class="form-label">Dateianhang</label>
<div class="file-loading">
<input id="input-folder-3" name="input-folder-3[]" type="file" accept=".jpeg,.jpg,.webp,.gif,.png.pdf" multiple>
</div>
</div>
<div class="row">
<div class="form-group mb-2 col">
<label class="mb-2">Kategorie <span id="howManyCategoriesMustBeProvided" class="text-danger-emphasis">(mindestens eine)</span></label>
<% requestOptions.categoriesFromDB.forEach(category => { %>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="<%= category.category %>" id="category<%= category.id %>" name="category[]">
<label class="form-check-label text-<%= category.cssClass %>" for="category<%= category.id %>">
<%= category.category %>
</label>
</div>
<% }) %>
</div>
<% if (user && user.isAdmin) { %>
<div class="col">
<label class="mb-2">Status</label>
<% requestOptions.statusFromDB.forEach((status) => { %>
<div class="form-group mb-2">
<input class="form-check-input" type="radio" value="<%= status.id %>"
id="status<%= status.id %>" name="statusId" <%= status.id === ADMIN_DEFAULT_STATUS ? 'checked' : '' %>>
<label class="form-check-label text-<%= status.cssClass %>" for="status<%= status.id %>">
<%= status.status %>
</label>
</div>
<% }) %>
</div>
<% } %>
<div class="col">
<label class="mb-2">Priorität</label>
<% requestOptions.prioritiesFromDB.forEach((priority, index) => { %>
<div class="form-group mb-2">
<input class="form-check-input" type="radio" value="<%= index +1 %>"
id="<%= priority.priority %>" name="priority" <%= index === DEFAULT_PRIORITY ? 'checked' : '' %>>
<label class="form-check-label text-<%= priority.cssClass %>" for="<%= priority.priority %>">
<%= priority.priority %>
</label>
</div>
<% }) %>
</div>
</div>
<span class="d-inline-block addrequest_submit_btn"
tabindex="0"
data-bs-toggle="popover"
data-bs-trigger="hover focus"
data-bs-placement="right"
data-bs-content="Du musst mindestens eine Kategorie auswählen.">
<button class="btn btn-primary" type="submit" disabled>Zur Überprüfung einreichen</button>
</span>
<p>Du kannst deine Anfrage nach dem Einreichen nicht mehr Bearbeiten.</p>
</form>
<%- include('partials/footer') %>
我在我的 utils.js 中实现了express-validator,如下所示:
const { body, validationResult } = require("express-validator");
const ensureValid = (req, res, next) => {
const result = validationResult(req);
if (!result.isEmpty()) {
return res.status(400).json({ errors: result.array() });
}
next();
};
module.exports = { body, ensureValid };
我也在使用路线。在这种情况下,我的 app.js 中是这样的:
const authRoutes = require('./routes/authRoutes');
app.use('/auth', authRoutes);
在我的 authRoutes.js 中,我现在尝试使用验证链,如下所示。
const { body, ensureValid } = require('../utils');
const authController = require('../controllers/authController');
router.post('/request/create',
body('title')
.escape()
.isString().withMessage('Der Titel muss ein String sein.')
.isLength({ max: 40 }).withMessage('Der Titel darf maximal 40 Zeichen lang sein.'),
body('description')
.escape()
.isString().withMessage('Die Beschreibung muss ein String sein.')
.isLength({ min: 1, max: parseInt(process.env.MAX_DESCRIPTION_CHARACTER_INPUT, 10) || 1000 })
.withMessage(`Die Beschreibung muss zwischen 1 und ${process.env.MAX_DESCRIPTION_CHARACTER_INPUT || 1000} Zeichen lang sein.`),
body('category')
.escape()
.isString().withMessage('Ungültige Kategorie.')
.custom((value, { req }) => {
const validCategories = [
process.env.categoryName1, process.env.categoryName2, process.env.categoryName3,
process.env.categoryName4, process.env.categoryName5, process.env.categoryName6,
process.env.categoryName7, process.env.categoryName8
];
if (!validCategories.includes(value)) {
throw new Error('Ungültige Kategorie.');
}
return true;
}),
body('priority')
.escape()
.isInt({ min: 1, max: 1 }).withMessage('Priorität muss eine gültige Nummer sein.'),
body('statusId')
.escape()
.isInt({ min: 1, max: 4 }).withMessage('Status muss eine gültige Nummer (1-4) sein.'),
ensureValid,
utils.uploadStoring.array('input-folder-3[]', 5),
authController.postNewRequest
);
我可以看到express-validator正在做一些事情,但无法遵循,为什么。输入没有通过,即使它应该
我的意见:
title: asdasd23
description: aer
input-folder-3[]: (binary)
category[]: Funktionswunsch
statusId: 2
priority: 2
验证错误:
{
"errors": [
{
"type": "field",
"value": "",
"msg": "Die Beschreibung muss zwischen 1 und 1000 Zeichen lang sein.",
"path": "description",
"location": "body"
},
{
"type": "field",
"value": "",
"msg": "Ungültige Kategorie.",
"path": "category",
"location": "body"
},
{
"type": "field",
"value": "",
"msg": "Priorität muss eine gültige Nummer sein.",
"path": "priority",
"location": "body"
},
{
"type": "field",
"value": "",
"msg": "Status muss eine gültige Nummer (1-4) sein.",
"path": "statusId",
"location": "body"
}
]
}
Wired:我正在记录我的请求,如下所示:
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`, req.body);
next();
});
输出:
POST /auth/request/create {}
没有express-validator中间件,它是相同的,但是以下(请求创建)中间件成功访问了req.body
我尝试了不同的验证链、输入和快速验证或导入。
在路由
/request/create
处理程序上,快速验证器首先运行,当您发送多部分请求时,它无法访问 req.body
,因为它尚未被处理,这就是为什么它是一个空对象 {}
,导致验证错误。
因此,在路由处理程序上,更改中间件的顺序,以便 multer 中间件首先运行,即在使用
req.body
的其他中间件之前运行,即快速验证器:
router.post('/request/create',
// run multer middleware before other using req.body
utils.uploadStoring.array('input-folder-3[]', 5),
// now run express validator
body('title')
.escape()
//...
// rest...
ensureValid,
authController.postNewRequest
);