我已经设置了一个具有正确权限的 gcloud 存储桶,并创建了一个具有存储创建者角色的服务帐户。我还编写了一个 go 后端,它生成签名的 url 并将其传递给下一个。签名的网址正在工作,因为我已经使用curl命令尝试过它并且它正确上传了所有内容。当我尝试从 nextjs 应用程序上传文件时出现问题。我有一个简单的表单和一个 onSubmit 处理程序,它从表单获取文件,将其传递给 formData 并上传整个内容。由于某种原因,我收到 403 Forbidden 错误消息。我尝试查看一些存储桶日志,但什么也没有。 (也许我没有正确设置日志记录)。我尝试对一些普通的 js 执行相同的操作,但仍然不起作用。
这是我的 nextjs 代码。
"use client"
import { getSignedURLs } from "../../upload/upload"
export default function Images(props) {
const submitImages = (e) => {
e.preventDefault()
const form = e.currentTarget
const data = new FormData(form)
const file = data.get("file")
getSignedURLs(1).then((r) => {
console.log(r[0])
let signed = r[0]
console.log(`${file.type}`)
fetch(signed, {
headers: {
"Content-Type": `${file.type}`,
},
method: "PUT",
body: file,
})
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok")
}
return response.json()
})
.then((data) => {
console.log("Response data:", data)
})
.catch((error) => {
console.error("There was a problem with your fetch operation:", error)
})
})
}
return (
<form id="uploadForm" onSubmit={submitImages} encType="multipart/form-data">
<input type="file" name="file" />
<button type="submit">Upload</button>
</form>
)
}
请注意,我已经测试了 getSignedUrl 函数,并且确信它返回正确的 url。 我也尝试过内容类型,但没有运气。 这现在是我的普通 js 了。
document
.getElementById("uploadForm")
.addEventListener("submit", function (event) {
event.preventDefault();
const formData = new FormData();
formData.append("file", this.file.files[0]);
getSignedURLs(1).then((r) => {
let signed = r[0];
fetch(signed, {
method: "PUT",
body: formData,
})
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
})
.then((data) => {
console.log("Response data:", data);
})
.catch((error) => {
console.error(
"There was a problem with your fetch operation:",
error
);
});
});
});
更新:
尝试了一些事情,我注意到,在使用 https://restninja.io/ 等网站发出请求时,一切正常。当我指定内容类型时,只有当我将其留空时,它才不起作用。这并不能解决我的问题,因为我仍然无法在我的 js 中重现所需的行为。
我通过添加解决了这个问题:
headers: {
"Content-Length": file.size,
"Content-Type": file.type,
},
到我的标题。