我有以下 PUG 模板:
extends layout
block append head
link(type='stylesheet', href='/stylesheets/mystyle.css', rel='stylesheet')
block layout-content
#chat-app
#chat.has-text-centered
h1.title Welcome to #{title}
section.section.chat-container
.container
.columns
.box.column.is-full
h2.title Messages
.chat-messages.has-text-left
p#messages
form#chatForm(action='/api/gemini', method='post', enctype="multipart/form-data")
.field.has-addons
p.control.is-expanded
input(class='input', id='prompt', type='text', placeholder='How can I help?')
p.control
input(class='input', id='image', type='file')
p.control
input(class='button is-success', type='submit', value='Post')
script.
document.querySelector("#chatForm").addEventListener("submit", async (e) => {
e.preventDefault();
const prompt = document.querySelector("#prompt").value;
if (prompt.trim()) {
const response = await fetch('/api/myapi', {
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' },
body: JSON.stringify({, prompt:, prompt})
});
const data = await response.json();
document.querySelector("#messages").innerHTML += `<p><strong>You:</strong> ${prompt}</p>`;
document.querySelector("#messages").innerHTML += `<p><strong>Server:</strong> ${data.message}</p><br>`;
document.querySelector("#prompt").value = '';
}
});
服务器端点使用
multer
:
api.post('/myapi', upload.single('image'), function (req, res, next) { myapp.Handle(req, res, next); });
我可以使用
multer
或 express-fileupload
。这里关注的是 PUG 模板中的内联脚本。如何在同一个发布请求中同时发送短信和上传文件?
使用 FormData 构造多部分请求:将文件附加到图像键,然后将其他数据(JSON)附加到其他键,并且只需将表单数据作为正文发布,没有内容类型标头,因为它会自动构造多部分请求(文件将在
req.file
中,其他数据以键/值形式在 req.body
中):
// get the image
const image = document.querySelector("#image").value
const formData = new FormData();
// add the image -> access via `req.file`, also, field name must be the same on the server (image -> image)
formData.append('image', image);
// add other stuff -> acess via `req.body`
formData.append('prompt', JSON.stringify({prompt}));
// send data - it automatically constructs multipart request, no need to manually add content type headers
const response = await fetch('/api/myapi', {
method: 'POST',
body: formData
});
或更短:您可以简单地传递表单元素,它会自动完成(所有 HTML 表单字段都将以键/值形式发送):
const response = await fetch('/api/myapi', {
method: 'POST',
body: new FormData(e.target)
})
;