node.js - Node JS - 尝试创建 PDF 时出现标题错误
问题描述
我正在关注如何使用 React/NodeJS 生成 PDF 的教程。PDF 正在我的文件中生成,但出现标题错误,导致 GET 请求无法正常工作。
0] 错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头
代理工作正常。我猜我没有正确处理ajax请求。
节点
const express = require('express');
const router = express.Router();
const { check, validationResult } = require('express-validator/check');
const pdf = require('html-pdf');
const pdfTemplate = require('../../documents');
// PDFs
router.post('/create', [
check('text', 'Text field is required').not().isEmpty()
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { text } = req.body;
res.json(text);
pdf.create(pdfTemplate(req.body), {}).toFile('result.pdf', (err) => {
if(err) {
return res.send(Promise.reject());
}
return res.send(Promise.resolve());
});
});
router.get('/fetch', (req, res) => {
return res.sendFile(path.resolve('result.pdf'));
});
module.exports = router;
反应
import React, { Component } from 'react';
import axios from 'axios';
import { saveAs } from 'file-saver';
class Form extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.handleForm = this.handleForm.bind(this);
this.state = {
text: ''
}
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value
})
}
handleForm(e) {
e.preventDefault();
const body = this.state;
axios.post('/api/pdfs/create', body)
.then(() => axios.get('/api/pdfs/fetch', { responseType: 'blob' }))
.then((res) => {
const pdfBlob = new Blob([res.data], { type: 'application/pdf' });
saveAs(pdfBlob, 'newPdf.pdf');
})
}
render() {
return (
<form onSubmit={this.handleForm}>
<input type="text" name="text" onChange={this.onChange} />
<button type="submit">Submit</button>
</form>
);
}
}
解决方案
您不需要在 POST 请求中发出 GET 请求来获取 POST 请求很容易返回的内容。您可以尝试确保服务器中的 POST 路由返回 pdf。
然后你的 ajax 调用看起来像这样
axios.post('/api/pdfs/create', body)
.then(res => {
const pdfBlob = new Blob([res.data], { type: 'application/pdf' });
saveAs(pdfBlob, 'newPdf.pdf');
})
在您的POST
路线控制器内部,您可以执行此操作...
(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { text } = req.body;
pdf.create(pdfTemplate(req.body), {}).toFile('result.pdf', (err, result) => {
if(err) {
return res.status(400).send(err);
}
return res.json({
text: text,
result: result // this contains the pdf file that is generated.
});
});
}
推荐阅读
- c++ - 在 C++ 中在运行时创建对象并命名它们
- c++ - 使用快速 I/O C++ 的不同答案
- safari - 在移动设备上使用 Safari 的传入 MediaStream 将无法播放
- ionic-framework - 带有 JavaScript 的 ionic 5 警报按钮
- c# - 像多维数组一样填充 C# 数组
- python - 基于数据的拐点研究
- android - 如何在设置栏中添加隐私政策部分 android studio
- td-engine - 在指定或可用的数据库注释中使用 tdengine restful 错误
- linux - 如果使用 shell 脚本在先前运行的进程文件(nohup.out)中发生任何异常,我如何重新启动进程?
- android - 是否有可以通过 React Native/Expo 访问的每个设备的唯一编号/代码/ID