使用请求对象上载图像文件

时间:2012-09-21 15:10:32

标签: javascript file-upload request firefox-addon-sdk

在我目前正在开发的Firefox扩展程序中,我已经尝试了几天使用Firefox Add-on SDK的request模块将图像文件上传到服务器。 我设法上传了一个文本文件,但我无法上传任何其他类型的文件。 我的最终目标是上传截图,以便我真的需要能够上传图片。 这是我目前的代码:

params= file.read("C:\\FullPath\h3nf5v2c.png", "b");

//multipart form data
boundary = "---------------------------132611019532525";
var snapShotUpload = Request({
    url : "https://myurl.com",
        headers : {
        "Referer" : "https://myurl.com",
    "Content-Type" : "multipart/form-data; boundary=" + boundary,
    },
    content :  "--" + boundary + "\r\n" + "Content-Disposition: form-data; name='Upload_FileName'; filename='h3nf5v2c.png'\r\nContent-Type: application/octet-stream\r\n\r\n" + params + "\r\n--" + boundary + "--\r\n",                          
    onComplete: function(response) {
        console.log(response.text);
    }                        
});
console.log("request built");
snapShotUpload.post();      

上传的图片已损坏,我无法阅读。

所以我的问题是:
如何使用Firefox Add-on SDK的request模块发布图像?

4 个答案:

答案 0 :(得分:2)

谢谢弗拉迪米尔,

我实际上并没有修改Request模块,只是简单地使用了XMLHttpRequest。 以下是我感兴趣的代码:

function sendImage(file){
        fName = "h3nf5v2c.png";

    // prepare the MIME POST data
    var boundaryString = '---------------------------132611019532525';
    var boundary = '--' + boundaryString;
    var requestbody = boundary + '\r\n'
            + 'Content-Disposition: form-data; name="Upload_FileName"; filename="'
            + fName + '"' + '\r\n'
            + 'Content-Type: image/png' + '\r\n'
            + '\r\n'
            + file.read()
            + '\r\n'
            + boundary + '--\r\n';

    // Send
    var http_request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
            .createInstance(Components.interfaces.nsIXMLHttpRequest);

    http_request.onreadystatechange = function() {
        if (http_request.readyState == 4 && http_request.status == 200) {
            console.log(http_request.responseText);
        }
    };

    http_request.open('POST', 'http://myUrl.com', true);
    http_request.setRequestHeader("Referer", "http://myUrl.com");                  
    http_request.setRequestHeader("Content-type", "multipart/form-data; boundary=" + boundaryString);
    //http_request.setRequestHeader("Connection", "close");
    http_request.setRequestHeader("Content-length", requestbody.length);
    http_request.sendAsBinary(requestbody);    

}

该函数的file参数是文件模块中的文件对象。

最后的sendAsBinary函数非常重要,因为我只在客户端工作,我不得不通过表单模拟插入。 如果您可以访问服务器端,发送映像的base64编码版本并在服务器端解码可能更简单。

答案 1 :(得分:1)

不幸的是,答案是:你做不到。 request模块主要用于传输url编码数据,因此假定不是字符串的任何内容都是包含需要编码的键值对的对象。因此,如果您需要发送多部分内容,发送字符串是唯一的选择XMLHttpRequest将始终将字符串编码为UTF-8,当您尝试发送原始二进制数据(例如图像数据)时,这将产生相当不理想的结果)。

use a FormData object要容易得多,但即使您创建了一个 - request模块也不会将其传递给XMLHttpRequest。没有简单的解决方案,只需修改request模块(附加SDK的文件packages/addon-kit/lib/request.js)。找到这一行:

let data = stringify(content);

将其更改为以下代码应该有效:

let {Ci} = require("chrome");
let data = content;
if (!(content instanceof Ci.nsIDOMFormData))
  data = stringify(content);

这可确保FormData个对象不会更改。

请注意,FormData中可能未定义Filemain.js。如果是这种情况,那么从任何JavaScript模块“窃取”它们都应该有效:

let {Cu} = require("chrome");
var {FormData, File} = Cu.import("resource://gre/modules/Services.jsm")

答案 2 :(得分:0)

我认为还有另一种方法可以在您的服务器上发布图像。您可以使用base64编码。 我从未测试过,但我在网上发现了this subject,它解释了如何转换图像。我希望这可以帮到你。

答案 3 :(得分:0)

可以简化您的生活的是使用FormData和XMLHttpRequests一起使用,如本例所示。

function uploadFiles(url, files) {
    var formData = new FormData();
    for (var i = 0, file; file = files[i]; ++i) {
        formData.append(file.name, file);
    }

    var xhr = new XMLHttpRequest();
    xhr.open('POST', url, true);
    xhr.onload = function(e) { ... };

    xhr.send(formData);  // multipart/form-data
}

document.querySelector('input[type="file"]').addEventListener('change', function(e) {
    uploadFiles('/server', this.files);
}, false);

来源:http://www.html5rocks.com/en/tutorials/file/xhr2/