在我目前正在开发的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
模块发布图像?
答案 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
中可能未定义File
和main.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);