代码之家  ›  专栏  ›  技术社区  ›  Robin-Hoodie

使用gapi将文件上载到Google Drive

  •  0
  • Robin-Hoodie  · 技术社区  · 6 年前

    我已经跟随 this article 以及 this SO answer 将包含元数据的文件上载到Google Drive时,会产生以下代码:

    readonly BOUNDARY = '--4561564891651634213217'; //Randomly mashed in numbers
    
    uploadToDrive(file: File /*<input type="file">.files[0]*/, fileName: string) {
        this.readFile(file)
            .then(base64File => {
              gapi.client.request({
                path: 'upload/drive/v3/files', method: 'POST', params: {
                  uploadType: 'multipart'
                }, headers: {
                  'Content-type': `multipart/related; boundary=${this.BOUNDARY}`,
                  'Content-length': file.size
                }, body: this.formatMultipartBody(file, fileName, base64File)
              })
                  .then(response => console.log('Upload success! ', response), error => console.error('Upload error! ', error));
            });
      }
    
    private readFile(file: File): Promise<string> {
        const fileReader: FileReader = new FileReader();
        return new Promise(resolve => {
          fileReader.readAsBinaryString(file);
          fileReader.onload = (event: any) => resolve(btoa(fileReader.result));
        });
      }
    
    private formatMultipartBody(file: File, fileName: string, base64File: string) {
        const delimiter = `\r\n--${this.BOUNDARY}\r\n`;
        const closeDelimiter = `\r\n--${this.BOUNDARY}--`;
        const metadata = {
          name: fileName, mimeType: file.type || 'application/octet-stream'
        };
        const body = `
        ${delimiter}
        Content-Type: application/json; charset=UTF-8\r\n\r\n
        Content-Transfer-Encoding: base64
        ${JSON.stringify(metadata)}
        ${delimiter}
        Content-Type: ${file.type || 'application/octet-stream'}\r\n
        ${base64File}
        ${closeDelimiter}
        `;
        return body;
      }
    

    无论我上传哪种类型的文件,我都会得到以下错误:

    {
     "error": {
      "errors": [
       {
        "domain": "global",
        "reason": "badContent",
        "message": "Unsupported content with type: application/octet-stream"
       }
      ],
      "code": 400,
      "message": "Unsupported content with type: application/octet-stream"
     }
    }
    

    即使文件具有扩展名(例如,包含文本“hello,world!”的hello.txt文件),也会出现此错误。请求中没有提到“应用程序/八位字节流”。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Robin-Hoodie    6 年前

    Google Drive API似乎对格式化请求体非常挑剔,这是 formatMultiPartBody 方法最终对我有效:

    private formatMultipartBody(file: File, fileName: string, base64Data: string): string {
        const delimiter = `--${this.BOUNDARY}`;
        const closeDelimiter = `--${this.BOUNDARY}--`;
        const metadata = {
          name: fileName, mimeType: file.type || 'application/octet-stream'
        };
        const body = `
        \n${delimiter}\
        \nContent-Type: application/json; charset=UTF-8\
        \n\n${JSON.stringify(metadata)}\
        \n${delimiter}\
        \nContent-Type: ${file.type || 'application/octet-stream'}\
        \nContent-Transfer-Encoding: base64\      
        \n\n${base64Data}\
        \n${closeDelimiter}`;
        return body;
      }