处理文件时出错:multipart:NextPart:EOF



我正在尝试构建一个小型应用程序,允许您批量上传大型文件。稍后我还会添加暂停功能。

我在循环中遇到了这个错误:处理文件时出错:multipart:NextPart:EOF

func main() {
router := gin.Default()
rg := router.Group("api/v1")
{
rg.POST("/photo", uploadFile)
}
router.Use(CORSMiddleware())
router.Run()
}
func uploadFile(c *gin.Context) {
mr, e := c.Request.MultipartReader()
if e != nil {
panic("Error reading request:" + e.Error())
}
client, e := storage.NewClient(c, option.WithAPIKey(uploadApiKey))
bucket := client.Bucket(uploadBucket)
for {
p, e := mr.NextPart()
if e == io.EOF {
break
} else if e != nil {
panic("Error processing file:" + e.Error())
}
w := bucket.Object(p.FileName()).NewWriter(c)
if _, e := io.Copy(w, p); e != nil {
panic("Error during chunk upload:" + e.Error())
} else if e := w.Close(); e != nil {
panic("Could not finalize chunk writing:" + e.Error())
}
}
}

客户端代码如下:

class FileToUpload {
static chunkSize = 512000;
static uploadUrl = 'http://localhost:8080/api/v1/photo';
readonly request: XMLHttpRequest;
readonly file: File;
readonly name: string;
currentChunkStartByte: number;
currentChunkFinalByte: number;
constructor(file: File, name: string) {
this.request = new XMLHttpRequest();
this.file = file;
this.name = name;
this.currentChunkStartByte = 0;
this.currentChunkFinalByte = FileToUpload.chunkSize > this.file.size ? this.file.size : FileToUpload.chunkSize;
}
uploadFile() {
let chunk: Blob = this.file.slice(this.currentChunkStartByte, this.currentChunkFinalByte);
this.request.overrideMimeType('application/octet-stream');
this.request.open('POST', FileToUpload.uploadUrl, true);
const randomNum = Math.random().toString().substr(2);
this.request.setRequestHeader('Content-Type', 'multipart/form-data; boundary=--'+randomNum);
this.request.setRequestHeader('Content-Range', `bytes ${this.currentChunkStartByte}-${this.currentChunkFinalByte}/${this.file.size}`);
this.request.onload = () => {
if(this.currentChunkFinalByte === this.file.size) {
// Do something once done with file
return;
}
this.currentChunkStartByte = this.currentChunkFinalByte;
this.currentChunkFinalByte = this.currentChunkStartByte + FileToUpload.chunkSize;
this.uploadFile();
}
this.request.send(chunk);
}
}

我已经检查了EOF,我不明白为什么我仍然会出现这个错误。有什么想法吗?

根据源代码,只有在流主体中没有找到关闭边界,但客户端将主体标记为已发送的情况下,才能返回由io.EOF组成的错误。在您的情况下,要么在标记文件内容结束的请求体中缺少边界,要么您没有在服务器端对其进行解析。

源代码:https://golang.org/src/mime/multipart/multipart.go#L339

在您的特定情况下,http.RequestMultipartReader()会预先解析您的边界,因此您不需要在那里做任何额外的操作(https://golang.org/src/net/http/request.go#L486)。同时,我没有看到任何代码会将文件边界附加到客户端的流。

不幸的是,这里没有提供负责将内容写入正文的代码,因此我不能在这里提示解决方案,但我非常确信客户端上随机生成的边界不会传递到除Content-Type标头之外的任何其他地方,这是您面临问题的主要原因。

请阅读有关多部分表单如何工作的更多信息,特别是在以下答案中:https://stackoverflow.com/a/8660740/8008395

最新更新