我正在尝试创建一个插件,该插件仅从网站获取一些数据并创建一个概念页面。显然,由于 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;
});
是否有任何包装器或任何方法来保留类型化界面,就像我在第一个示例中那样?
我可以创建一个自定义获取函数来传递给 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;
}
});