将请求传递给后台脚本

问题描述 投票:0回答:1

我正在尝试创建一个插件,该插件仅从网站获取一些数据并创建一个概念页面。显然,由于 CORS 问题,我无法在

content_script
中使用官方 SDK。

解决方案应该是使用

chrome.runtime.sendMessage
chrome.runtime.onMessage
,但这只会隐藏
Client
界面,并且很难从
content_script

使用

例如,这个简单的代码,它具有自动完成功能:

function saveToNotion () {
  const result = await chrome.storage.local.get('notionToken')
  const notion = new Client({auth: result.notionToken})

  // THIS gives a CORRS error
  notion.databases.retrieve()
}

需要更改为这样的内容:

// On content_script.tsx
function getDatabases () {
  chrome.runtime.sendMessage('retrieve_databases')
}

// On background.tsx
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  const result = await chrome.storage.local.get('notionToken')
  const notion = new Client({auth: result.notionToken})

  return true
})

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.type === "retrieve_databases") {
    const result = await chrome.storage.local.get('notionToken')
    const notion = new Client({auth: result.notionToken})
    sendResponse(notion.databases.retrieve())
  }
  return true;
});

是否有任何包装器或任何方法来保留类型化界面,就像我在第一个示例中那样?

typescript google-chrome-extension
1个回答
0
投票

我可以创建一个自定义获取函数来传递给 Client 对象:

function saveToNotion () {
  const result = await chrome.storage.local.get('notionToken')
  const notion = new Client({auth: result.notionToken, fetch: bgFetch})

  // THIS gives a CORRS error
  notion.databases.retrieve()
}



export const bgFetch: SupportedFetch = (url, init) => {
  return new Promise((resolve, reject) => {
    chrome.runtime.sendMessage(
      {
        type: 'bgFetch',
        url: url,
        init: init,
      },
      (response) => {
        console.log("resolved response", response)
        if (chrome.runtime.lastError) {
          reject(new Error(chrome.runtime.lastError.message));
        } else {
          resolve({
            ok: response.ok,
            text: () => response.text,
            headers: response.headers,
            status: response.status,
          });
        }
      }
    );
  });
};

然后,在

background.ts

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.type === 'bgFetch') {
    const url: SupportedRequestInfo = request.url;
    const init: SupportedRequestInit = request.init;

    fetch(url, init)
      .then((response) => {
          const toSend: SupportedResponse = response
          // You can only send JSON
          response.text().then((txt) => sendResponse({
            ok: response.ok,
            text: txt,
            headers: response.headers,
            status: response.status,
          }))
      })
      .catch((error) => {
        console.error('Fetch error:', error);
        sendResponse({ ok: false, status: 500, text: () => Promise.resolve(error.message) });
      });

    // Return true to indicate that you want to send a response asynchronously
    return true;
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.