Upload a File in a Google Chrome Extension
I'm writing an extension for Chrome, and I need to upload a file from the page the use开发者_JAVA百科r is currently on to my server to be processed, I cannot figure out how to upload the file though. I considered just passing the link to the server and having the server download the file, however if the site requires authentication this will not work. Is it possible to upload a file via a Chrome extension to my server?
I've recently developed a Chrome extension which retrieves content from a page, and sends it to the server.
The following approach was used:
- File downloads: Get the
src
property of an<img>
element, for example. - Fetch the file from the Cache - use
XMLHttpRequest
from the background page. - Use a Web Worker in the background page to handle the upload.
Side note, to take the checksum of the image, Crypto-JS: MD5 can be used. Example (where xhr
is the XMLHttpRequest
object with responseType
set to arraybuffer
, see Worker demo):
var md5sum = Crypto.MD5( new Uint8Array(xhr.response) );
Full example
Content script
// Example: Grab the first <img> from the document if it exists.
var img = document.images[0];
if (img) {
// Send the target of the image:
chrome.runtime.sendMessage({method: 'postUrl', url: img.src});
}
Background script (with Worker)
chrome.runtime.onMessage.addListener(function(request) {
if (request.method == 'postUrl') {
var worker = new Worker('worker.js');
worker.postMessage(request.url);
}
});
Web Worker
// Define the FormData object for the Web worker:
importScripts('xhr2-FormData.js')
// Note: In a Web worker, the global object is called "self" instead of "window"
self.onmessage = function(event) {
var resourceUrl = event.data; // From the background page
var xhr = new XMLHttpRequest();
xhr.open('GET', resourceUrl, true);
// Response type arraybuffer - XMLHttpRequest 2
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (xhr.status == 200) {
nextStep(xhr.response);
}
};
xhr.send();
};
function nextStep(arrayBuffer) {
var xhr = new XMLHttpRequest();
// Using FormData polyfill for Web workers!
var fd = new FormData();
fd.append('server-method', 'upload');
// The native FormData.append method ONLY takes Blobs, Files or strings
// The FormData for Web workers polyfill can also deal with array buffers
fd.append('file', arrayBuffer);
xhr.open('POST', 'http://YOUR.DOMAIN.HERE/posturl.php', true);
// Transmit the form to the server
xhr.send(fd);
};
FormData
for Web workers POLYFILL
Web workers do not natively support the FormData
object, used to transmit multipart/form-data
forms. That's why I've written a polyfill for it. This code has to be included in the Web worker, using importScripts('xhr2-FormData.js')
.
The source code of the polyfill is available at https://gist.github.com/Rob--W/8b5adedd84c0d36aba64
Manifest file:
{
"name": "Rob W - Demo: Scraping images and posting data",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["contentscript.js"]
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": ["http://*/*", "https://*/*"]
}
Relevant documentation
- Message passing Google Chrome Extensions
chrome.runtime.onMessage
Google Chrome ExtensionsXMLHttpRequest
Level 2 W3c specificationFormData
(XHR2) MDN- ArrayBuffer responses (XHR2) HTML5 rocks (note: arraybuffer responses are deprecated in favor of typed arrays, the polyfill has been updated to reflect this change)
The simplest solutions seems to be for your extension to send the file's URI to your server, and then your server-side code will download it from the page into the server and process it.
Create a server-side script like http://mysite.com/process.php?uri=[file's URI goes here] that will process the given file. Use AJAX to call this URL (more info at http://code.google.com/chrome/extensions/xhr.html ). The script will return the processed file, which you could then use in your extension.
You should checkout the following:
chrome.extension.sendRequest() and chrome.extension.onRequest()
You can read more about them here: http://code.google.com/chrome/extensions/messaging.html
Basically you will setup the page on the server to watch for the Chrome extension, and once they connect you will need to have a javascript that will do the upload task for you.
I haven't tested this out, but it may get you where you need to be. Also you may want to read the Long-lived connections section.
Goodluck
精彩评论