400 多部分文件上传错误请求

Posted

技术标签:

【中文标题】400 多部分文件上传错误请求【英文标题】:400 Bad Request on Multipart File Upload 【发布时间】:2017-02-11 12:14:38 【问题描述】:

我正在尝试通过改造将图像上传到PushBullet API。

在upload-request 之后,我触发了分段上传。

通过改造我得到这个错误:

"error":"code":"invalid_request","type":"invalid_request","message":"Invalid multipart body.","cat":"o(^・x・^)o","error_code":"invalid_request"

这个问题只出现在我的 java 代码中,而不是 PAW HTTP-Client。

# PAW generated Request
POST /upload-legacy/bcSWXnBjNIwpkej7CxfIHFz0ugXO6yhf HTTP/1.1
Content-Type: multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__
Host: upload.pushbullet.com
Connection: close
User-Agent: Paw/3.0.12 (Macintosh; OS X/10.11.6) GCDHTTPRequest
Content-Length: 34508

--__X_PAW_BOUNDARY__
Content-Disposition: form-data; name="file"; filename="cat.jpg"
Content-Type: image/jpeg

...

# Retrofit generated Request
POST https://upload.pushbullet.com/upload-legacy/ZZ4fLcqt2WFQmlbKTDlgcYXtB3KiCs3M http/1.1
Content-Type: multipart/form-data; charset=utf-8
Content-Length: 2012
Content-Disposition: form-data; name="file"; filename="1475501429665_motion_detected.jpg"
Content-Type: image/jpeg; charset=utf-8
Content-Length: 1772

...

我认为重要的区别是Part 中的Content-Length。 我找到了这个issue,但这是否意味着 PushBullet API 不符合 HTTP 规范?

任何帮助将不胜感激。

【问题讨论】:

对我来说唯一突出的是 Content-Length 在您的 Retrofit 上传尝试中明显更小。我会尝试对这两种方法使用相同的 jpg 来排除这个问题。 @Trigona 没错,因为我用 Retrofit 发送了一个小得多的图像:) 【参考方案1】:

我在基于 javascript 的 Google Apps Script 中遇到了同样的问题,但我希望我的解决方案可以帮助遇到此问题的其他人。我在这里使用了 TANAIKE 构建多部分请求的方法:https://gist.github.com/tanaikech/d595d30a592979bbf0c692d1193d260c

我成功上传 JPEG 的最终结果如下所示:


    // https://docs.pushbullet.com/v8/#upload-request
    // Assuming var picResponseJSON is your JSON results from successful upload-request
    var uploadJSON = 
      awsaccesskeyid: picResponseJSON.data.awsaccesskeyid,
      acl: picResponseJSON.data.acl,
      key: picResponseJSON.data.key,
      signature: picResponseJSON.data.signature,
      policy: picResponseJSON.data.policy,
      "content-type": picResponseJSON.data["content-type"],
    ;

    // https://gist.github.com/tanaikech/d595d30a592979bbf0c692d1193d260c
    var boundary = "xxxxxxxxxx";
    var data = "";
    for (var i in uploadJSON) 
      data += "--" + boundary + "\r\n";
      data +=
        'Content-Disposition: form-data; name="' +
        i +
        '"; \r\n\r\n' +
        uploadJSON[i] +
        "\r\n";
    
    data += "--" + boundary + "\r\n";
    data +=
      'Content-Disposition: form-data; name="file"; filename="' +
      fileTitle +
      '"\r\n';
    data += "Content-Type:" + mimeType + "\r\n\r\n";
    var payload = Utilities.newBlob(data)
      .getBytes()
      .concat(DriveApp.getFileById(fileID).getBlob().getBytes())
      .concat(Utilities.newBlob("\r\n--" + boundary + "--").getBytes());
    var options3 = 
      method: "post",
      contentType: "multipart/form-data; boundary=" + boundary,
      payload: payload,
      muteHttpExceptions: true,
    ;

    // Send request
    var uploadResponse = UrlFetchApp.fetch(picResponseJSON.upload_url, options3);

    // Confirm it's successful
    if (uploadResponse.getResponseCode() == 204) 
      console.log("Success! File: " + picResponseJSON.file_url);
    

请注意,负载中的 Blob 函数是 Google Apps 脚本的一部分,因此请根据您的语言进行相应修改。

【讨论】:

以上是关于400 多部分文件上传错误请求的主要内容,如果未能解决你的问题,请参考以下文章

Abp Zero AJAX请求(文件上传)出现400 bad request 错误问题解决

当前请求不是多部分请求 Spring Boot 和 Postman(上传 json 文件加上额外字段)

使用 Alamofire(多部分数据)上传带有额外参数的 .PDF 文件时出错

尝试使用 MERN 上传图像时出现 400 错误请求错误

AWS S3 通过预签名 URL 上传返回 400 错误请求

使用多部分请求将大文件上传到服务器并使用休息套件读取进度