通过xhr上传文件到Flask服务器
Upload files to Flask server via xhr
我正在尝试使用 Flask 和表单创建文件上传,但效果不佳。我完全不知道问题出在哪里。我尝试了多个教程并查看了许多堆栈溢出线程都无济于事。
Flask 似乎根本没有收到任何表单数据,我不明白为什么。这是我的 python 上传端点代码:
@app.route("/upload", methods=["post"])
def upload_endpoint():
# Just prints ImmutableMultiDict([]) twice
print(request.form)
print(request.files)
return "Success", 200
这是我上传过程相关的js:
// Creates and returns an input element with all needed tags and event listeners
function createInput() {
const input = document.createElement("input")
input.setAttribute("type", "file")
input.setAttribute("multiple", "true")
input.setAttribute("name", "file")
input.addEventListener("change", () => {
submitInput(input)
}, false)
return input
}
// Takes an input tag, puts it in a form, and submits it via xhr
function submitInput(input) {
const form = document.createElement("form")
form.appendChild(input)
const xhr = new XMLHttpRequest()
xhr.open("POST", "/upload")
// Calculates and logs upload progress
xhr.upload.addEventListener("progress", (e) => {
const percent = e.lengthComputable ? (e.loaded / e.total) * 100 : 0
console.log(percent.toFixed(2))
})
xhr.setRequestHeader("Content-Type", "multipart/form-data")
xhr.send(new FormData(form))
}
// Handles for when element is clicked. .click() is used to create the popup dialogue for selecting a fike
centerDrop.addEventListener("click", () => {
const input = createInput()
input.click()
return false
}, false)
// Handles for when a file is dropped into the browser
dropArea.addEventListener("drop", (e) => {
const input = createInput()
input.files = e.dataTransfer.files
submitInput(input)
}, false)
我一直在用 200kb 的图像测试上传功能,但是根据浏览器中的开发控制台,正在创建的请求的大小小于 1kb。为什么图像似乎没有包含在请求中?
与其以编程方式将整个输入添加到表单中,不如尝试仅添加其文件:
function submitInput(input) {
...
form.append("file", input.files) // Instead of form.appendChild(input)
...
}
然后在 BE 上访问它:
print("files:", request.files['file'])
问题是我试图自己处理设置请求 headers。只需删除这一行:xhr.setRequestHeader("Content-Type", "multipart/form-data")
对我有用。
故事的寓意是让 XMLHttpRequest 为您处理 headers,在提交表单数据的情况下,它知道自己在做什么。
我正在尝试使用 Flask 和表单创建文件上传,但效果不佳。我完全不知道问题出在哪里。我尝试了多个教程并查看了许多堆栈溢出线程都无济于事。
Flask 似乎根本没有收到任何表单数据,我不明白为什么。这是我的 python 上传端点代码:
@app.route("/upload", methods=["post"])
def upload_endpoint():
# Just prints ImmutableMultiDict([]) twice
print(request.form)
print(request.files)
return "Success", 200
这是我上传过程相关的js:
// Creates and returns an input element with all needed tags and event listeners
function createInput() {
const input = document.createElement("input")
input.setAttribute("type", "file")
input.setAttribute("multiple", "true")
input.setAttribute("name", "file")
input.addEventListener("change", () => {
submitInput(input)
}, false)
return input
}
// Takes an input tag, puts it in a form, and submits it via xhr
function submitInput(input) {
const form = document.createElement("form")
form.appendChild(input)
const xhr = new XMLHttpRequest()
xhr.open("POST", "/upload")
// Calculates and logs upload progress
xhr.upload.addEventListener("progress", (e) => {
const percent = e.lengthComputable ? (e.loaded / e.total) * 100 : 0
console.log(percent.toFixed(2))
})
xhr.setRequestHeader("Content-Type", "multipart/form-data")
xhr.send(new FormData(form))
}
// Handles for when element is clicked. .click() is used to create the popup dialogue for selecting a fike
centerDrop.addEventListener("click", () => {
const input = createInput()
input.click()
return false
}, false)
// Handles for when a file is dropped into the browser
dropArea.addEventListener("drop", (e) => {
const input = createInput()
input.files = e.dataTransfer.files
submitInput(input)
}, false)
我一直在用 200kb 的图像测试上传功能,但是根据浏览器中的开发控制台,正在创建的请求的大小小于 1kb。为什么图像似乎没有包含在请求中?
与其以编程方式将整个输入添加到表单中,不如尝试仅添加其文件:
function submitInput(input) {
...
form.append("file", input.files) // Instead of form.appendChild(input)
...
}
然后在 BE 上访问它:
print("files:", request.files['file'])
问题是我试图自己处理设置请求 headers。只需删除这一行:xhr.setRequestHeader("Content-Type", "multipart/form-data")
对我有用。
故事的寓意是让 XMLHttpRequest 为您处理 headers,在提交表单数据的情况下,它知道自己在做什么。