【问题标题】:How can I use the Google API in a chrome extension?如何在 chrome 扩展中使用 Google API?
【发布时间】:2019-05-01 10:56:18
【问题描述】:

我现在正在寻找如何在 chrome 扩展程序中使用 Google API 的几个小时。我要做的就是解析网站的内容并将其作为新事件插入 Google 日历。我得到了解析和一切,但似乎不可能在 Chrome 扩展中使用 Google API。我只是在单击我的 chrome 扩展程序中的按钮时尝试编写一个示例事件,但它一直拒绝加载 Google API 并出现此错误:

Refused to load the script 'https://apis.google.com/js/platform.js' because it violates the following Content Security Policy directive: "script-src 'self' blob: filesystem: chrome-extension-resource:". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

我的 manifest.json:

{
    "manifest_version": 2,

    "name": "DVB2Calender",
    "description": "This extension will export the current viewed schedule to your Google Calender.",
    "version": "1.0",

    "content_security_policy": "script-src 'self' https://apis.google.com/; object-src 'self'",

    "browser_action": {
     "default_icon": "icon.png",
     "default_popup": "popup.html"
    },
    "permissions": [
     "activeTab"
     ]
}

我的 popup.html

<!doctype html>
<html>
  <head>
    <title>DVB2Calender</title>
    <meta http-equiv="Content-Security-Policy" content="default-src *;">
    <script src="popup.js"></script>
    <script src="https://apis.google.com/js/platform.js" async defer>
    </script>
  </head>
  <body>

    <h1>DVB to Calender</h1>
    <button id="exportToCalender">Export this calender to Google Calender!</button>

  </body>
</html>

我的 popup.js:

document.addEventListener('DOMContentLoaded', function() {
    var checkPageButton = document.getElementById('exportToCalender');
    checkPageButton.addEventListener('click', function() {

        chrome.tabs.getSelected(null, function(tab) {
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');
            script.type = 'text/javascript';
            script.src = "https://apis.google.com/js/client.js?onload=callbackFunction";
            head.appendChild(script);

            d = document;
            var download = d.getElementsByClassName('icon-link ico-calender')[6];
            var request = makeHttpObject();
            request.open("GET", download, true);
            request.send(null);
            request.onreadystatechange = function() {
                if (request.readyState === 4) {
                    var resultText = request.responseText;
                    array = CSVToArray(resultText, ":");
                    alert(resultText);

                    var resource = {
                        "summary": "Appointment",
                        "location": "Somewhere",
                        "start": {
                        "dateTime": "2011-12-16T10:00:00.000-07:00"
                        },
                        "end": {
                        "dateTime": "2011-12-16T10:25:00.000-07:00"
                        }
                    };
                    var request = gapi.client.calendar.events.insert({
                    'calendarId': 'primary',
                    'resource': resource
                    });
                    request.execute(function(resp) {
                    console.log(resp);
                    });
                }
            };
        }
    }
}

【问题讨论】:

  • 不确定这是否会有所不同,但请尝试将content_security_policy 中的https://apis.google.com/ 更改为https://apis.google.com(不带最后一个斜杠)。在我发现的examples 中,最后一个斜杠从未使用过。此外,popup.js 文件中的所有代码(包括 chrome.tabs.getSelected 侦听器)都在弹出窗口中运行:您可能需要一个内容脚本来满足您的目的
  • 我会试试的!我认为 Michal 的回答中提到的重新加载也存在问题。昨天我花了很多时间试图让它与内容脚本一起工作,但最终放弃了,我今天再试一次。

标签: javascript google-chrome-extension google-calendar-api google-api-js-client


【解决方案1】:

我使用 reactJS 做了一个 chrome 扩展,利用 Google Calendar API 来创建日历事件。我已经粘贴了下面的链接,希望它可以帮助人们了解如何正确实现上述用例。

Project Link(请为 repo 加注星标,如果这对您有帮助)

要使用谷歌日历 API,先决条件是首先配置 Oauth2,因为谷歌日历 API 需要身份验证令牌。您的清单文件必须包含配置 OAuth 的更改。

在chrome扩展的manifest文件中配置好Oauth2后,下面的函数会帮你调用创建事件。

function createMeeting() {
  chrome.identity.getAuthToken({ interactive: true }, function (token) {
    console.log(token);

    
    //details about the event
    let event = {
      summary: 'Google Api Implementation',
      description: 'Create an event using chrome Extension',
      start: {
        'dateTime': '2015-05-28T09:00:00-07:00',
        'timeZone': 'America/Los_Angeles'
      },
      end: {
        'dateTime': '2015-05-28T09:00:00-07:00',
        'timeZone': 'America/Los_Angeles'
      }
    };

    let fetch_options = {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(event),
    };

    fetch(
      'https://www.googleapis.com/calendar/v3/calendars/primary/events',
      fetch_options
    )
      .then((response) => response.json()) // Transform the data into json
      .then(function (data) {
        console.log(data);//contains the response of the created event
      });
  });
}

确保您的清单文件包含以下条目:

"oauth2": {
    "client_id": "your id",
    "scopes": [
      "profile email",
      "https://www.googleapis.com/auth/calendar",
      "https://www.googleapis.com/auth/calendar.readonly"
    ]
  },
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "permissions": [
      "identity",
      "identity.email"
    ]

分解:

  1. 要在 Chrome 扩展程序中使用 Google API,您首先需要做的是登录。现在有这么多的“安全限制”,你不能再像网站一样导入那个 API js。相反,您需要使用浏览器 api 来授予访问权限,a.k.a. chrome.identity.getAuthToken (https://developer.chrome.com/docs/extensions/reference/identity/#method-getAuthToken)。 但是要让这个浏览器 api 工作,你仍然需要做很多其他的工作,例如manifest、packing extension 等。但是你可以通过搜索这个浏览器 api 来了解这些东西以及它们与 Google 相关的原因。

  2. STEP 1 成功后,您将获得带有chrome.identity.getAuthToken 的令牌。现在您需要知道如何使用此令牌请求 Google API。就像这个页面中的例子 (https://developers.google.com/streetview/publish/first-app), 我们 可以看到令牌可以在像这样authorization: Bearer YOUR_ACCESS_TOKEN 的标头中发送。所以现在我们知道我们可以使用fetch/ XMLHttpRequest 使用此标头让 Google API 为用户工作。

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。代码示例可能非常有用。如果链接页面发生更改,仅链接响应可能会失效。
  • @borchvm 谢谢你的建议。我已根据您的建议进行了处理,并进行了必要的更改。
  • 这将使您对身份验证流程的控制有限。用户将只能选择 Chrome 用户帐户,而不能选择任何 google 帐户。
  • 事实上,如果你想办法“获取”谷歌账号ID(我的是一个21位整数),你可以使用platform.identity.getAuthToken({account: { id: _21_DIGIT_GOOGLE_ID_, ... }, ...)登录一个账号,即使没有登录浏览器。
【解决方案2】:

您似乎刚刚忘记重新加载扩展包。请注意,每次更改扩展代码时,都需要重新加载(可在此处完成chrome://extensions/)以使代码更改生效。

要检查客户端脚本是否可以使用,建议添加 onload 回调,如下所示:

window.callbackFunction = function(){
  alert('client.js ready')
  // here goes google client api calls
}

onload回调函数的名称由脚本url中的onload参数指定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    相关资源
    最近更新 更多