Chrome extension fetch fails when uploading PDF with FormData to Express/multer backend
High agreement — the answer is well-supported across models.
Models agree on
- ✓CORS (Cross-Origin Resource Sharing) is a primary cause of fetch failures and requires server-side configuration using `cors` middleware in Express, potentially specifying the extension's origin.
- ✓Do not manually set the `Content-Type` header in your `fetch` request when using `FormData`; the browser handles it automatically to `multipart/form-data`.
- ✓Multer configuration is critical, specifically ensuring `upload.single()` uses the correct field name (e.g., 'file') matching `formData.append('file', ...)` and customising `limits` for file size.
- ✓Chrome extension manifest permissions are necessary for network requests, and `manifest.json` must specify access to the backend URL(s).
Points of disagreement
- ~One model suggested `fileSystem` permission which is generally for accessing local files and not directly for network uploads, while others correctly focused on `host_permissions` in `manifest.json` for network access.
- ~While all agreed on `cors` configuration, there was a slight difference in emphasis on specifying the exact `chrome-extension://ID` origin versus a more general `app.use(cors())` for testing.
When a Chrome extension encounters a "fetch fails" error while uploading a PDF using FormData to an Express/Multer backend, the problem most commonly lies in cross-origin restrictions (CORS), incorrect FormData or fetch API usage, or misconfigurations within your Multer setup.
1. Cross-Origin Resource Sharing (CORS)
An extension operating in a different origin than your backend will likely be blocked by default browser security policies. To resolve this:
-
Server-Side Solution: Your Express server must explicitly allow requests from your extension. Use the
corsmiddleware: javascript const express = require('express'); const cors = require('cors'); const app = express();app.use(cors()); // For testing, this allows all origins
// For production, specify your extension ID: // app.use(cors({ // origin: 'chrome-extension://%EXTENSION_ID%', // Replace %EXTENSION_ID% with your actual extension ID // credentials: true, // }));
2. Chrome Extension fetch and FormData Usage
Incorrect handling of FormData or fetch can prevent the upload:
-
Content-TypeHeader: Do NOT manually set theContent-Typeheader when sendingFormData. The browser automatically sets it tomultipart/form-datawith the correct boundary. Manually setting it can lead to415 Unsupported Media Typeerrors or parsing failures. javascript const formData = new FormData(); formData.append('file', fileBlob, 'document.pdf'); // 'file' should match your Multer field namefetch('https://your-backend/api/upload', { method: 'POST', body: formData, // Do NOT manually set 'Content-Type' header here! }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); // Or response.text() if your server doesn't return JSON }) .then(data => console.log('Success:', data)) .catch(error => console.error('Error:', error));
-
Extension Permissions: Your
manifest.jsonmust include the necessary permissions for the backend URL. Without these, network requests to external servers may be blocked:{ "manifest_version": 2, // Or 3 "name": "Your Extension", "version": "1.0", "permissions": [ "activeTab", "http://your-backend.com/", "https://your-backend.com/" ] }
3. Express/Multer Backend Configuration
The server-side setup using Multer must be correct to receive and process the file:
-
Multer Initialization: Ensure Multer is correctly initialized and configured for file uploads. The field name used in
formData.append('file', ...)must match the argument inupload.single('file'). javascript const multer = require('multer'); const upload = multer({ dest: 'uploads/' }); // or configure storageapp.post('/api/upload', upload.single('file'), (req, res) => { if (!req.file) { return res.status(400).send('No file uploaded.'); } console.log(req.file); // The uploaded file object res.status(200).send('File uploaded successfully'); });
-
File Size Limits: Multer has a default file size limit (often 1MB) which can cause uploads of larger PDFs to fail. Increase this limit as needed: javascript const upload = multer({ dest: 'uploads/', // or configure storage limits: { fileSize: 50 * 1024 * 1024 } // Example: 50MB limit });
4. Debugging Steps
- Chrome DevTools Network Tab: This is your primary tool. Look for red network requests. Pay attention to the response status codes (e.g.,
400 Bad Request,403 Forbidden,415 Unsupported Media Type,500 Internal Server Error) and the detailed error messages. Check request headers, especiallyContent-Type. - Server Logs: Regularly inspect your Express server's console for Multer-specific errors (e.g.,
LIMIT_FILE_SIZEerrors, parsing issues) or other backend exceptions. - Test with Postman/Insomnia: Before involving the extension, confirm your backend endpoint works as expected by sending a
multipart/form-datarequest with a PDF using a tool like Postman. This isolates whether the issue is client-side or server-side. - Extension Logging: Use
console.log()within your extension's background scripts or content scripts to trace flow and variable values, helping pinpoint where thefetchcall might be failing before it even hits the network.
By systematically checking these areas, you should be able to identify and resolve the "fetch fails" error.
You just saw open-source models answer
Want GPT-5, Claude, Gemini & more on the same question?
Sign in free to run any question against frontier models — side by side, same synthesis, honest comparison.