Google 驱动器 API 出现奇怪的 CORS 问题

Strange CORS issue with Google Drive API

Google 驱动器 API, files.update:
https://developers.google.com/drive/api/v3/reference/files/update

这个 API 给出了 CORS 错误,奇怪的是在我正在创建的同一个驱动器应用程序中,在同一个域上(我正在直接在线测试它):

developers.google.com 上的文档没有提到 CORS 问题,一个 API 可以而另一个不能的问题可能是什么?

创建和更新的 2 个函数在这里,但不应该是代码问题,因为 CORS 是关于脚本的起源,而函数在同一页上:

// Create new file in Gdrive
// See: https://developers.google.com/drive/api/v3/reference/files/create
// See: https://tanaikech.github.io/2018/08/13/upload-files-to-google-drive-using-javascript
async function gdrive_create_file(Folder_Id,File_Name,Binobj){
    var Metadata = {
        "name":     File_Name,    // Filename at Google Drive
        "mimeType": "text/plain", // mimeType at Google Drive
        "parents":  [Folder_Id],  // Folder ID at Google Drive
    };

    // Here gapi is used for retrieving the access token.
    var Access_Token = gapi.auth.getToken().access_token;
    var Form         = new FormData();
    Form.append("metadata", new Blob([JSON.stringify(Metadata)], {type: 'application/json'}));
    Form.append("file",     Binobj);

    // Make request to Gdrive
    var [Lock,Unlock] = new_lock();
    var File_Id       = null;
    var Xhr           = new XMLHttpRequest();

    // Gdrive to return id as indicated in 'fields=id'
    Xhr.open(
        "post",
        "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id"
    );
    Xhr.setRequestHeader("Authorization", "Bearer "+Access_Token);
    Xhr.responseType = "json";
    Xhr.onload = ()=>{
        log("[Dad's TE] Gdrive file id:",Xhr.response.id); // Retrieve uploaded file ID.
        File_Id = Xhr.response.id;

        if (File_Id==null)
            alert("Failed to create file in Gdrive!");

        Unlock();
    };
    Xhr.send(Form);

    // Wait to get resulting file id
    await Lock;
    return File_Id;
}

// Update a file in Gdrive
log("DEBUG HERE: 0");
async function gdrive_update_file(File_Id,File_Name,Binobj){
    var Metadata = {
        "name":     File_Name,   // Filename at Google Drive
        "mimeType": "text/plain" // mimeType at Google Drive
    };

    // Here gapi is used for retrieving the access token.
    var Access_Token = gapi.auth.getToken().access_token;
    var Form         = new FormData();
    Form.append("metadata", new Blob([JSON.stringify(Metadata)], {type: 'application/json'}));
    Form.append("file",     Binobj);

    // Make request to Gdrive
    var [Lock,Unlock] = new_lock();
    var Xhr           = new XMLHttpRequest();

    // Gdrive to return id as indicated in 'fields=id'
    Xhr.open(
        "patch",
        `https://www.googleapis.com/upload/drive/v3/files/${File_Id}?uploadType=multipart&fields=id`
    );
    Xhr.setRequestHeader("Authorization", "Bearer "+Access_Token);
    Xhr.responseType = "json";
    Xhr.onload = ()=>{
        log("[Dad's TE] Gdrive file id:",Xhr.response.id); // Retrieve uploaded file ID.
        File_Id = Xhr.response.id;

        if (File_Id==null)
            alert("Failed to update file in Gdrive!");

        Unlock();
    };
    alert("DEV ERROR: See CORS error in console log!");
    Xhr.send(Form);

    // Wait to get resulting file id
    await Lock;
    return File_Id;
}

new_lock函数:

function new_lock(){
    var Unlock,Lock = new Promise((Res,Rej)=>{ Unlock=Res; });
    return [Lock,Unlock];
}

在你的脚本中,修改如下?在我的环境中,当我测试你的脚本时,我确认了同样的错误。在这种情况下,当"patch"修改为"PATCH"时,错误被移除。

修改后的脚本:

发件人:

Xhr.open(
    "patch",
    `https://www.googleapis.com/upload/drive/v3/files/${File_Id}?uploadType=multipart&fields=id`
);

收件人:

Xhr.open(
    "PATCH",
    `https://www.googleapis.com/upload/drive/v3/files/${File_Id}?uploadType=multipart&fields=id`
);

Xhr.open(
    "PATCH",
    "https://www.googleapis.com/upload/drive/v3/files/" + File_Id + "?uploadType=multipart&fields=id"
);
  • 另外,请删除 alert("DEV ERROR: See CORS error in console log!");。使用时,始终显示。请注意这一点。
  • console.log(Xhr.response);被放入Xhr.onload = ()=>{,,,}时,可以看到API的响应。

注:

  • 在我用"PATCH"更新文件后,当我用"patch"测试脚本时,没有发生错误。但是,当使用 "patch" 的脚本更新新文件时,再次出现此类错误。那么在这种情况下,使用 "PATCH" 而不是 "patch" 怎么样?

  • 作为简单的测试脚本,下面的脚本怎么样?

      function gdrive_update_file(File_Id,File_Name,Binobj){
        var Metadata = { "name": File_Name, "mimeType": "text/plain" };
        var Access_Token = gapi.auth.getToken().access_token;
        var Form = new FormData();
        Form.append("metadata", new Blob([JSON.stringify(Metadata)], { type: 'application/json' }));
        Form.append("file", Binobj);
        var Xhr = new XMLHttpRequest();
        Xhr.open(
          "PATCH",
          "https://www.googleapis.com/upload/drive/v3/files/" + File_Id + "?uploadType=multipart&fields=id"
        );
        Xhr.setRequestHeader("Authorization", "Bearer " + Access_Token);
        Xhr.responseType = "json";
        Xhr.onload = () => {
          console.log(Xhr.response);
        };
        Xhr.send(Form);
      }
    

参考文献: