Firefox扩展开发:如何在新标签页发送POST请求打开指定页面
Hey, let's figure out how to get your Firefox extension to open a new tab with POST data to your server-controlled page—since the Chrome trick isn't working and XHR only gives you plain text responses, we've got a couple solid fixes here:
Option 1: Use Firefox's browser.tabs.create API (the cleanest approach)
Firefox's tabs.create does support sending POST data directly, but you might have missed some formatting that's stricter than Chrome's implementation. Here's the correct setup:
// Prepare your POST data (URL-encoded for standard form submissions) const postData = new URLSearchParams({ user_id: '123', payload: 'your-custom-data' }); // Create the new tab with POST request browser.tabs.create({ url: 'https://your-server.com/target-page', postData: postData.toString(), contentType: 'application/x-www-form-urlencoded' // Critical: matches data format }).catch(err => { console.error('Failed to create tab with POST:', err); });
If you need to send multipart/form-data (like file uploads), swap in FormData instead:
const formData = new FormData(); formData.append('profile_pic', fileBlob); formData.append('bio', 'Hello from the extension!'); browser.tabs.create({ url: 'https://your-server.com/upload-page', postData: formData });
Option 2: Dynamic Hidden Form Submission (100% browser-compatible)
If the API approach hits CSP snags or edge cases, this classic form-submit trick works reliably across all browsers. It mimics a regular user submitting a form, which loads your target page in a new tab with POST data:
function openTabWithPost(url, data) { // Create a hidden form element const form = document.createElement('form'); form.style.display = 'none'; form.method = 'POST'; form.action = url; form.target = '_blank'; // Forces new tab // Add all data fields as hidden inputs Object.entries(data).forEach(([key, value]) => { const input = document.createElement('input'); input.type = 'hidden'; input.name = key; input.value = value; form.appendChild(input); }); // Attach form to page, submit, then clean up document.body.appendChild(form); form.submit(); document.body.removeChild(form); } // Usage example openTabWithPost('https://your-server.com/target-page', { key1: 'value1', key2: 'value2' });
Quick Fix for Your XHR Issue (if you need parsed responses)
If you ever need to use XHR and get more than plain text, just set the responseType to match what you're expecting. For example, to get a full HTML document:
const xhr = new XMLHttpRequest(); xhr.open('POST', 'https://your-server.com/target-page'); xhr.responseType = 'document'; // Parses response as HTML DOM xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onload = function() { if (xhr.status === 200) { // Access the parsed HTML directly const responseHtml = xhr.response.body.innerHTML; console.log('Loaded HTML:', responseHtml); } }; xhr.send(new URLSearchParams({ key: 'value' }).toString());
Since you control the target page, you can also pass data after the tab loads (though this doesn't send an initial POST request). Here's how:
In your extension background script:
// Open the target page first browser.tabs.create({ url: 'https://your-server.com/target-page' }).then(tab => { // Wait for the page to finish loading const listener = (tabId, info) => { if (tabId === tab.id && info.status === 'complete') { // Send data to the page browser.tabs.sendMessage(tabId, { type: 'EXTENSION_DATA', payload: { user: 'test', data: 'foo' } }); browser.tabs.onUpdated.removeListener(listener); } }; browser.tabs.onUpdated.addListener(listener); });
In your target page's script:
// Listen for messages from the extension browser.runtime.onMessage.addListener((message) => { if (message.type === 'EXTENSION_DATA') { // Handle the data (e.g., render it on the page) console.log('Got data from extension:', message.payload); } });
内容的提问来源于stack exchange,提问作者Marek Teuchner

