XMLHttpRequest中表单数据上的Javascript二进制字符串连接

XMLHttpRequest中表单数据上的Javascript二进制字符串连接,javascript,google-chrome-extension,xmlhttprequest,binaryfiles,multipartform-data,Javascript,Google Chrome Extension,Xmlhttprequest,Binaryfiles,Multipartform Data,我正在编写一个Chrome扩展,需要构建一个自定义表单数据来上传一个Zip文件(我不能使用真正的HTML表单)到服务器(不是我的)。 我在这里找到了一个方法- (最后一节-处理二进制数据) 它适用于明文文件,但我想发送二进制的Zip文件 JavaScript似乎无法处理二进制和非二进制的连接,并在我的文件中添加了一些0Xc2字符): 我还找到了一个解决方案, 但它使用Components.classes[“@mozilla.org/io/string input stream;1”],这在Chr

我正在编写一个Chrome扩展,需要构建一个自定义表单数据来上传一个Zip文件(我不能使用真正的HTML表单)到服务器(不是我的)。 我在这里找到了一个方法- (最后一节-处理二进制数据)

它适用于明文文件,但我想发送二进制的Zip文件

JavaScript似乎无法处理二进制和非二进制的连接,并在我的文件中添加了一些0Xc2字符):

我还找到了一个解决方案, 但它使用
Components.classes[“@mozilla.org/io/string input stream;1”]
,这在Chrome扩展中不可用

如何将二进制zip文件与字符串连接起来并将其上载到服务器

函数sendData(zipBinary){
var XHR=new XMLHttpRequest();
var boundary=“----WebKitFormBoundary3n9vu9ZOkCPW4HAw”;
var前缀=”;
var postfix=“”;
前缀+=“--”+边界+“\r\n”;
前缀+='内容配置:表单数据;'
+'name=“”+”上传文件“+”;'
+'filename=“”+”hello.zip“+”\r\n';
前缀+='内容类型:'+'应用程序/x-zip压缩'+'\r\n';
前缀+='\r\n';
后缀+='\r\n';
//完成后,我们“关闭”身体的请求
后缀+=“-”+边界+“-”;
后缀+='\r\n';
XHR.addEventListener('load',函数(事件){
警报('是的!数据已发送,响应已加载');
});
XHR.addEventListener('error',函数(事件){
警惕(‘哎呀!有点不对劲’);
});
XHR.open('POST','https://example.com');
setRequestHeader('Content-Type','multipart/form data;boundary='+boundary);
发送(前缀+zipBinary+后缀)//您读过您链接的文章中的吗?因为这是通过XMLHttpRequest API发送文件的最佳解决方案。与字符串连接相比,此API的优势在于,文件可以以流式方式上载,而不必在发送之前在内存中完全缓冲

假设
zipBinary
Blob
File
对象,您可以按如下方式上载文件:

函数sendData(zipBinary){
var xhr=new XMLHttpRequest();
var fd=新Formdata();
fd.append('hello.zip',zipBinary);
xhr.onload=函数(){
//请求已完成!请使用xhr.status和/或xhr.responseText
//检查服务器的响应状态代码和响应正文。
};
xhr.onerror=函数(){
//网络错误。
};
xhr.open('POST','https://example.com/');
xhr.send(fd);
}
如果
zipBinary
不是一个or对象,而是一个二进制数据字符串,则可以将其转换为具有指定MIME类型的Blob,如下所示:

函数sendData(zipBinary){
var zipBinaryBytes=新的Uint8Array(zipBinary.length);
对于(变量i=0;i
(注意:
application/zip
是zip文件的官方MIME类型,而不是
application/x-zip-compressed


如果您是HTTP协议专家,并且确实希望完全手工编写HTTP请求正文,那么您需要发送一个类型化数组而不是字符串,因为XMLHttpRequest API会在将数据传递到服务器之前发送。这可以使用应用于代码的自Chrome 38+完成,如下所示:

//Was:XHR.send(前缀+zipBinary+postfix);
//新的
send(新的textcoder().encode(前缀+zipBinary+postfix));
注意:您很少需要手动构造请求正文。除非您知道自己在做什么,必须手动构造请求正文通常表明您做错了