Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
415 views
in Technique[技术] by (71.8m points)

forms - Grab file with chrome extension before upload

using my chrome extension i would like to grab a file(and maybe change it) before it gets uploaded to a website. Particularly from file-inputs. Put another way if i select a file with an input[type=file] i want my chrome extension to interrupt any submit and take the file. Then my extension applies its magic to the file and after that the file may be submitted/uploaded. How can i approach this?

On problem occurs with the file path. If i grab the vaule of a file-input it always changes the actual path to " C:fakepath" due to HTML5 standard and compatibility issues. How can i access the file then? Maybe it is saved temporarily in some chrome storage?

EDIT: Well, i managed to read the file selected in the file input like this:

var file;
$('input[type=file]').change(function(e){
    file = e.target.files[0];
    var reader = new FileReader();      
    reader.onload = function (event) {
        console.log(event.target.result);  //contains the file data
        //maybe change data and use filewriter  

    };      
    reader.readAsDataURL(file);
};

Now i would like to use a FileWriter to write to e.target.files[0]

I followed this tutorial: http://www.html5rocks.com/en/tutorials/file/filesystem/ but i am not able to create a proper FileWriter.

It is not necessary to write to the original file on the disk - might not even possible - but i need to change the data that is used to upload in the corresponding file-input form field.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There's no defined API for a Chrome extension to intercept the payload of a request (work in progress).

That being said, you can use a Content script to add an event listener which:

  1. Cancels the normal form submission.
  2. Reads the file as an ArrayBuffer using the FileReader API.
  3. Modify the resulting ArrayBuffer after wrapping it in a view.
  4. Create a Blob from the modified data.
  5. Reconstruct the form by creating a FormData instance, then use the .append(name, value[, filename]) method.
    Note: In the example below, I did not include the form reconstruction method. I only included the file upload part. There are two approaches to reconstruct the form:

    1. Write a method which is specific to your form.
    2. Write a general form-parsing method, which takes care of nameless/disabled/unchecked/... elements. If you want to take this route, have a look at the W3 specification for the Form submission algorithm.
  6. Submit the data using XMLHttpRequest. Note: If you're running this code in the context of your Chrome extension, don't forget to explicitly whitelist the URL at the permissions section in the manifest file.

Here's an example of the implementation:

// Reference to the form:
var form = document.forms["uploadForm"];
form.addEventListener('submit', function(ev) {
    ev.preventDefault(); // Cancel submission

    var fileInput = form.querySelector('input[type="file"]');
    var file = fileInput.files[0];
    if (!file) return; // No file selected

    var fileReader = new FileReader();
    fileReader.onload = function() {
        var arraybuffer = fileReader.result;
        // To manipulate an arraybuffer, wrap it in a view:
        var view = new Uint8Array(arraybuffer);
        view[0] = 0; // For example, change the first byte to a NULL-byte

        // Create an object which is suitable for use with FormData
        var blob = new Blob([view], {type: file.type});

        // Now, the form reconstruction + upload part:
        var formData = new FormData();
        formData.append(fileInput.name, blob, file.name);
        // ... handle remainder of the form ...

        // Now, submit the form
        var xhr = new XMLHttpRequest();
        xhr.open('POST', form.action);
        xhr.onload = function() {
            // Do something. For example:
            alert(xhr.responseText);
        };
        xhr.onerror = function() {
            console.log(xhr); // Aw. Error. Log xhr object for debugging
        }
        xhr.send(formData);
    };
    fileReader.readAsArrayBuffer(file);
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...