javascript - 从 html 上传文件用 js 烧瓶服务器
问题描述
我正在尝试将文件从 JS 前端发送到 Flask 后端。但我的烧瓶后端似乎没有收到任何文件。它在进入烧瓶后端 HTML 页面并手动提交时有效,但我希望前端将文件发送到后端。
这是有问题的javascript:
function send() {
const formData = new FormData();
const files = document.getElementById("file");
formData.append("file", files.files[0]);
const requestOptions = {
headers: {
"Content-Type": "multipart/form-data",
},
mode: "no-cors",
method: "POST",
files: files.files[0],
body: formData,
};
console.log(requestOptions);
fetch("http://localhost:5000/upload", requestOptions).then(
(response) => {
console.log(response.data);
}
);
}
export default function App() {
return (
<div className="App" id="App">
<header className="App-header">
<Button variant="outlined" component="label" size="large">
Load Audio
<input
id="file"
type="file"
onChange={send}
hidden
/>
</Button>
</header>
</div>
);
}
这是用于处理传入请求的烧瓶 python 脚本:
@app.route("/upload", methods=["GET", "POST"])
def upload():
if request.method == 'POST':
if 'file' not in request.files:
print(1)
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
print(2)
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
print(3)
filename = secure_filename(file.filename)
session["id"] = filename
file.save(os.path.join('UPLOAD', filename))
return redirect(url_for('uploaded',
filename=filename))
return render_template('upload.html')
它打印 1,因此找不到文件。
如果它有用,这里有一个调试print(request.headers)
:
Host: localhost:5000
Connection: keep-alive
Content-Length: 412313
Sec-Ch-Ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
Content-Type: multipart/form-data
Accept: */*
Origin: http://localhost:3000
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
我在网上阅读了很多关于如何在这种情况下上传文件的信息,但我无法让它工作。能得到一些帮助会很棒!
解决方案
您在 Flask 中的文件处理似乎恰到好处。然而,你指定Content-Type
标题的方式对 Flask 来说似乎很模糊。
在运行代码的简化示例时,我尝试通过以下方式使用 cURL 对其进行测试:
curl -XPOST http://localhost:5000/upload -F file=@TestFile.txt
这样 Flask 就知道文件已上传,我可以在以下位置看到它request.files
:
ipdb> request.files
ImmutableMultiDict([('file', <FileStorage: 'TestFile.txt' ('text/plain')>)])
还引起我注意的是,Content-Type
有一个指定的边界:
('Content-Type', 'multipart/form-data; boundary=------------------------aa8098f7b7fa6c61')
这让我假设Content-Type: multipart/form-data
手动指定似乎不起作用。
由于您尝试通过 JS 进行上传fetch
,请考虑查看此处。他们也不建议手动设置标题。
推荐阅读
- scala - 迁移到 Scala3 后范围基准测试缓慢
- python - 使用 PyAudio 读取流时,每 1024 字节(微)帧后减少 1 毫秒的延迟
- python - 熊猫时差计算列不更新
- python - 重新绑定可迭代导致 UnbindLocalError (?)
- asynchronous - 在 Blazor Webassembly 中初始化服务
- java - aws camunda zeebe ClientStatusException:超过 19.999991631 秒后的最后期限
- reactjs - 如果数据不是未定义的,你怎么能映射?
- javascript - 函数返回未捕获的引用错误
- node.js - 如何解决错误读取 ECONNRESET 公牛库
- bash - bash 中 printf 的默认 FORMAT 字符串是什么?