Dan D.
Dan D.

Reputation: 8557

Strange CORS issue with Google Drive API

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

This API is giving CORS error, the strange thing is in the same drive app that I'm creating, on the same domain (I'm testing it directly online):

The documentation on developers.google.com doesn't mention about CORS issue, what could be the problem that one API is ok while the other is not?

The 2 functions to create and update are here but shouldn't be a code issue, since CORS is about the origin of script while the functions are on the same page:

// 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;
}

The new_lock function:

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

Upvotes: 0

Views: 1768

Answers (1)

Tanaike
Tanaike

Reputation: 201358

In your script, how about modifying as follows? In my environment, when I tested your script, I confirmed the same error. In this case, when "patch" is modified to "PATCH", the error was removed.

Modified script:

From:

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

To:

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

or

Xhr.open(
    "PATCH",
    "https://www.googleapis.com/upload/drive/v3/files/" + File_Id + "?uploadType=multipart&fields=id"
);
  • And also, please remove alert("DEV ERROR: See CORS error in console log!");. When this is used, this is always displayed. Please be careful this.
  • When console.log(Xhr.response); is put in Xhr.onload = ()=>{,,,}, you can see the response from the API.

Note:

  • After I updated the file with "PATCH", when I tested the script with "patch", no error occurred. But, when new file is updated with the script with "patch", such error occurred again. So in this case, how about using "PATCH" instead of "patch"?

  • As the simple test script, how about the following script?

      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);
      }
    

References:

Upvotes: 2

Related Questions