javascript - 尝试将文件上传到 Google Drive 时不断收到“需要登录”错误

标签 javascript google-chrome-extension google-drive-api google-chrome-app drive

我正在编写一个 chrome 扩展程序,它将拦截某些下载(当前为 .doc 和 .docx 文件),而是获取这些文件并自动将它们上传到您的 Google 驱动程序文件夹。这是我的 list :

{
    // Default manifest crap.
    "manifest_version": 2,
    "name": "App",
    "description": "SpartaHack 2016 application",
    "version": "1.0",
    "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html"
    },
    // Content security needed to access gapi script.
    "content_security_policy": "script-src 'self' https://apis.google.com; object-src 'self'",
    // Need to view downloads, and identity for obvious reasons.
    // The other two permissions allow the script to access files that are outside our domain. 
    "permissions": [
        "downloads",
        "identity",
        "http://*/",
        "https://*/"
    ],
    // Gives us the auth information.
    "oauth2": {
        "client_id": "id",
        "scopes": [
            "https://www.googleapis.com/auth/drive.file",
            "https://www.googleapis.com/auth/userinfo.profile"
        ]
    },
    // Scripts that are always running.
    // Client.js has the gapi script, eventPage is our code.
    "background": {
        "scripts": ["client.js", "eventPage.js"]
    }
}

如果需要,我还编写了以下执行授权的方法:

chrome.identity.getAuthToken({
    "interactive": true
}, sendAuthToken);

function sendAuthToken(token) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=' + token, true);
    xhr.onload = function() {
        console.log(xhr.response);
    }

    //TODO: 
    xhr.send();
    console.log(token);
    watchDownloads();
}

这个片段是我从某处的一个例子中找到的。似乎仅进行授权是不够的,我还必须使用此 token 发送对用户信息的请求。这部分不会给我带来任何麻烦 - token 已正常记录,并且记录的响应按预期显示了我的所有信息。

这是 watchDownloads() 的样子:

function watchDownloads() {
    chrome.downloads.onCreated.addListener(function(download) {
        if(download.url.endsWith(".doc") || download.url.endsWith(".docx")) {
            // Get blob from URL
            var xhr = new XMLHttpRequest();
            xhr.open("GET", download.url, true);
            xhr.responseType = "blob";

            xhr.onload = function(error) {
                if(this.status == 200) {
                    insertFile(this.response, function(resp) {
                        console.log(resp);
                    });
                }
            };

            xhr.send();
        }
    });
}

简而言之,它寻找我关心的两个文件扩展名,如果它看到它们,它应该使用另一个 HTTP 请求直接获取该文件到文件的 url,然后使用此方法将它上传到我们的驱动器中,主要是从在线样本中拼凑而成:

function insertFile(fileData, callback) {
    const boundary = "-------314159265358979323846";
    const delimiter = "\r\n--" + boundary + "\r\n";
    const close_delimiter = "\r\n--" + boundary + "--";

    //TODO: Remove
    console.log(fileData);

    var reader = new FileReader();
    reader.readAsBinaryString(fileData);
    reader.onload = function(error) {
        var contentType = fileData.type || "application/octet-stream";
        var metadata = {
            // "title": fileData.filename,
            "title": "Potato",
            "mimeType": contentType
        };

        var base64Data = btoa(reader.result);
        var multipartRequestBody =
            delimiter +
            "Content-Type: application/json\r\n\r\n" +
            JSON.stringify(metadata) +
            delimiter +
            "Content-Type: " + contentType + "\r\n" +
            "Content-Transfer-Encoding: base64\r\n\r\n" +
            base64Data +
            close_delimiter;

        //TODO: Remove
        console.log(multipartRequestBody);

        var request = gapi.client.request({
            "path": "/upload/drive/v3/files",
            "method": "POST",
            "params": {
                "key": "key",
                "uploadType": "multipart"
            },
            "headers": {
                "Content-Type": 'multipart/mixed; boundary="' + boundary + '"'
            },
            "body": multipartRequestBody
        });

        //TODO: Remove
        console.log(request);

        if(!callback) {
            callback = function(file) {
                console.log(file)
            };
        }

        request.execute(callback);
    }
}

这是它失败的地方。我似乎无法让它工作,因为每次都会出现以下错误:

enter image description here

我必须做什么才能在这里正确登录?我尝试在 header 中添加 Authorization 属性,但出现相同的错误。

最佳答案

这可能会帮助其他人遇到这个问题。
如果您确实授权使用 JWT,请确保包括 auth: <your jwtClient>在您的 API 调用中,例如:

首先,获取 token :

// Configure JWT auth client
var privatekey = require("./<secret>.json")
var jwtClient = new google.auth.JWT(
  privatekey.client_email,
  null,
  privatekey.private_key,
  ['https://www.googleapis.com/auth/drive']
);

// Authenticate request
jwtClient.authorize(function (err, tokens) {
  if (err) {
    return;
  } else {
    console.log("Google autorization complete");
  }
});

然后,调用 API (但不要忘记 auth:jwtClient 部分)

drive.files.create({
    auth: jwtClient,
    resource: {<fileMetadata>},
    fields: 'id'
  }, function (err, file) {
    if (err) {
      // Handle error
    } else {
      // Success is much harder to handle
    }
});

关于javascript - 尝试将文件上传到 Google Drive 时不断收到“需要登录”错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35676817/

相关文章:

python - 带有python的谷歌驱动器文件夹中的文件列表

javascript - 使用 Javascript 通过电子邮件发送 Google 表单数据

javascript回调闭包 undefined variable

javascript - .js, setInterval, .load(), clearInterval()

firefox - Chrome 是否违反了内容安全政策?

javascript - Chrome 扩展程序 : Play a notification sound when a web page element content changes

JavaScript OOP 和 Chrome 扩展 api 中的异步方法

google-drive-api - Google 云端硬盘 SDK - 500 : Internal Server error: File uploads successfully most of the time

javascript - 访问 JSON-LD 对象产生错误是谷歌结构化数据测试工具

javascript - react 复选框 : event. preventDefault() 中断 onChange 函数 - 为什么?