上传前使用chrome扩展程序抓取文件

时间:2012-07-23 22:43:50

标签: forms file file-upload google-chrome-extension

使用我的chrome扩展程序我想在上传到网站之前抓取一个文件(也许可以更改它)。特别是来自文件输入。 换句话说,如果我选择一个带有输入[type = file]的文件,我希望我的chrome扩展程序能够中断任何提交并获取文件。然后我的扩展程序将其魔法应用于文件,之后可以提交/上传文件。 我怎么能接近这个?

文件路径出现问题。如果我抓住文件输入的vaule,由于HTML5标准和兼容性问题,它总是将实际路径更改为“C:\ fakepath \”。 我怎么才能访问该文件呢?也许它暂时保存在一些镀铬存储器中?

编辑: 好吧,我设法读取文件输入中选择的文件,如下所示:

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);
};

现在我想使用FileWriter写入e.target.files [0]

我遵循了这个教程: http://www.html5rocks.com/en/tutorials/file/filesystem/ 但我无法创建一个合适的FileWriter。

没有必要写入磁盘上的原始文件 - 可能甚至不可能 - 但我需要在相应的文件输入表单字段中更改用于上载的数据。

1 个答案:

答案 0 :(得分:5)

Chrome扩展程序没有定义API来拦截请求的有效负载(work in progress)。

话虽如此,您可以使用Content script添加一个事件监听器:

  1. 取消正常表单提交。
  2. 使用ArrayBuffer API将文件作为FileReader读取。
  3. 将结果ArrayBuffer包装在view
  4. 后对其进行修改
  5. 从修改后的数据中创建Blob
  6. 通过创建FormData实例重新构建表单,然后使用.append(name, value[, filename])方法。
    注意:在下面的示例中,我做了包含表单重建方法。我只包括文件上传部分。有两种方法可以重建形式:

    1. 编写特定于表单的方法。
    2. 编写一般的表单解析方法,该方法负责无名/禁用/未检查/ ...元素。如果您想采用这条路线,请查看W3 specification for the Form submission algorithm
  7. 提交数据using XMLHttpRequest。注意:如果您在Chrome扩展程序的上下文中运行此代码,请不要忘记在permissions section in the manifest file明确将该网址列入白名单。
  8. 以下是实施的一个例子:

    // 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);
    });