skip to Main Content

I’m building a Chrome extension that needs to fetch data from Wiktionary.
Due to CORS restrictions, I can’t directly make requests from the Chrome extension to Wiktionary. Therefore, I want to use a proxy backend hosted on Vercel to handle these requests and send the data back to the extension.
Here’s my current server.js for the backend:

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const fetch = require('node-fetch'); 
const app = express();
const PORT = process.env.PORT || 3000;

// Allow CORS for my Chrome extension
app.use(cors({
  origin: ['chrome-extension://my-extension-id'], 
  methods: ['GET', 'POST', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

app.use(bodyParser.json());
app.use(express.static('public'));

// Health check route
app.get('/', (req, res) => {
  res.send('mainpage');
});

// Proxy route to fetch data from Wiktionary
app.get('/proxy/:word', async (req, res) => {
  const word = req.params.word
    .replaceAll('ō', 'o')
    .replaceAll('ā', 'a')
    .replaceAll('ī', 'i')
    .replaceAll('ū', 'u');
  try {
    const response = await fetch(`https://en.wiktionary.org/wiki/${word}`);
    if (!response.ok) {
      throw new Error('Failed to fetch data from Wiktionary');
    }
    const text = await response.text(); 
    res.send(text); 
    console.log(`Successfully fetched data for word: ${word}`);
  } catch (error) {
    console.error('Error fetching from Wiktionary:', error);
    res.status(500).send('Error fetching from Wiktionary');
  }
});

// Start the server
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

Here is the frontend code piece that uses the backend

fetch(`https://myappbackendurlexample.vercel.app/fetch/${word}`)
          .then(response => response.text())
          .then(html => {
            const parser = new DOMParser();
            const baseDoc = parser.parseFromString(html, 'text/html');
            //following implementations
          })

And my manifest.json

{
//related fields
  "manifest_version": 3,
  "permissions": ["storage","https://myappbackendurlexample.vercel.app/*"],
  "host_permissions": ["https://myappbackendurlexample.vercel.app/*"],
  "content_security_policy": {
    "script-src": "'self'",
    "object-src": "'self'"
  },
  "background": {
    "service_worker": "server.js"
  }
  
}

However, even though my backend can get the data from wiktionary successfully, my frontend always has
these errors, as the backend probably doesnt let the front end visit.

Access to fetch at ‘https://myappbackendurlexample.vercel.app/fetch/gestarum’ from origin ‘chrome-extension://extension_ID’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.Understand this error
myappbackendurlexample.vercel.app/fetch/gestarum:1

Failed to load resource: net::ERR_FAILEDUnderstand this error
Inflections.js:17

Uncaught (in promise) TypeError: Failed to fetch
at HTMLButtonElement. (Inflections.js:17:9)

Since chrome extension does not allow node,I tried to fetch the data directly and add wikitionary to permissions and host_permissions. I published this version seperately and its still in review so I am trying to use this local version and vercel backend.
I also tried setting up a proxy route in my Express server to forward requests to wiktionayr but doesnt really work.
I checked the logs on Vercel but did not find any additional information explaining the 401 Unauthorized error.
As running the code on localhost works fine,I expected that the Chrome extension would be able to make successful fetch requests to my backend (hosted on Vercel), which would in turn fetch data from Wiktionary and return it to the extension.

2

Answers


  1. This is answer is based on my understanding that you are having trouble querying data from a third party API in your localhost.

    If you want to test your API in your local and your requests are getting rejected due to cross origin policies, set NODE_TLS_REJECT_UNAUTHORIZED environment variable to 0 in your .env file locally.

    OR, you can add this line in your server.js file you shared above,
    process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

    Remember, setting this variable to 0 is not recommended and should never be used for production as it disables certificate verification and makes requests insecure.
    You will just need to add the target domain in your verified list of addresses for production.

    Login or Signup to reply.
  2. You’re getting a CROS error because you’re calling the request from the content script. If you execute the request from the service worker page or from the iframe, then CORS error will not occur. Accordingly, in order to create communication between the content script and the service worket page, you need to use chrome.runtime.sendMessage

    Here is an article on this topic: https://developer.chrome.com/docs/extensions/reference/api/runtime?hl=ru#method-sendMessage

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search