Fetch Data in Chrome Extension V3

This approach can be used to retrieve any host server

bitbug
JavaScript in Plain English

--

I am working on a Chrome Extension that utilizes the TinyPNG open API to compress images. Previously, it was easy for the content script to fetch content from any host without encountering the CORS problem in V2. However, things have changed in V3, and an error occurred when trying to fetch the API in the content script due to CORS restrictions.

Changes to permissions in manifest.json did not solve the issue, so alternative solutions need to be explored.

Using the background script to fetch data

The Chrome extension can utilize a background script, similar to a service worker, to improve the overall browsing experience. Additionally, the Event System can be used to initiate an HTTP request from the content script.

// content script
chrome.runtime.sendMessage({ type: 'image', url: '<https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F958e1994-be0c-4d8a-ac7c-ea26c8971188%2FUntitled.png?id=57ffe85c-75f2-43fa-8d9c-372f58809836&table=block&spaceId=9047f58e-5ddf-46fd-a4b7-6d1a8d133c25&width=1900&userId=5cbec8d7-83db-40b8-9fbe-9f6c37c38b1d&cache=v2>' }, response => {
console.log(response)
})

And in the background script, register a listener.

// background script
chrome.runtime.onMessage.addListener(function (message, sender, senderResponse) {
if (message.type === "image") {
fetch('<https://api.tinify.com/shrink>', {
method: 'POST',
headers: {
'Authorization': `Basic ${btoa('api:xxxxxx')}`,
'Content-Type': 'application/json'
},

body: JSON.stringify({source: {url: message.url}})
}).then(res => {
return res.json();
}).then(res => {
senderResponse(res);
})
}
return true
});

If we conduct a test, there may still be an error.

And we can config the host_permission field in the manifest.json to make this host credible.

{
"manifest_version": 3,
"name": "Notion Image Compress",
"description": "A browser extension made for Notion",
"version": "1.0.0",
"permissions": [
"activeTab"
],
// and the api host
"host_permissions": ["<https://api.tinify.com/shink>"],
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"js": ["content.js"],
"matches": [
"<https://notion.so/*>",
"<https://www.notion.so/*>"
]
}
]
}

After doing so, give it another try and it should function properly as intended.

Summary

In Chrome Extension V3, we can utilize the background script (which is similar to a service worker) to fetch data from cross-origin hosts by configuring the host_permissions.

To retrieve server data from the content script, one may need to use the Event and the sendMessage and onMessage methods of the chrome.runtime API.

--

--