- 开始前:这是一个100%的客户端问题,忘记服务器端语言、我如何处理上传等--我正在比较一个已知的HTTP文件上传请求和一个jQuery生成的 AJAX 请求,理论上应该做同样的事情。*
背景:我正在为tinyMCE编写一个文件上传插件,其中一部分涉及到允许支持拖放图片上传的浏览器--具体来说,firefox中的tinyMCE会在文件系统映像被拖放到tinyMCE编辑器时创建一个带有base64 src的img,这是我目前的用例,以后可能会扩展。
我的目标是获取base64数据,并使用jQuery模拟表单提交以将其上传到服务器。我已经有了一个正常的基于HTML表单的方法。
获取base64数据非常简单:
$('img[src^="data:"]', ed.getDoc()).each(function(){
var data = /data:(image\/\w+);base64,(.*)/gmi.exec(this.src), format, ext;
if (data){
format = data[1];
ext = format.split('/')[1];
data = atob(data[2]);
}
else{
// blah, not supported
}
});
准备POST数据同样简单:
var boundary = '--------------------boundary' + (new Date).getTime();
data = '\r\n' + boundary + '\r\n' +
'Content-Disposition: form-data; name="file-upload"; filename="uploaded_image.' + ext + '"\r\n' +
'Content-Type: ' + format + '\r\n\r\n' +
data + '\r\n' +
boundary + '--'
;
剩下的就是将它发送到服务器:
$.ajax({
type: 'POST',
url: '/upload/',
contentType: 'multipart/form-data; boundary=' + boundary.slice(2),
data: data
});
服务器“正确地”处理POST(它看到文件并将其保存到磁盘,一切正常),但生成的图像严重损坏--它不会在浏览器中显示,而且它的jpeg header完全错误,更不用说它比本Map像大了大约33%(服务器上12 K,而本Map像为9 K)。
使用Firebug的Net选项卡,看起来没有什么问题--事实上,除了Content-Type请求头中多了一个charset=UTF-8
和缺少漂亮的打印POST数据之外,这个 AJAX 请求看起来与对应的表单POST * 完全 * 一样。
表单上传:
-----------------------------191891488320550623041315726177
Content-Disposition: form-data; name="file-upload"; filename="file.jpg"
Content-Type: image/jpeg
ÿØÿàJFIFHHÿÛC...
AJAX 上传:
--------------------boundary1375846064929
Content-Disposition: form-data; name="file-upload"; filename="file.jpeg"
Content-Type: image/jpeg
ÿÃÿà JFIFHHÿÃC...
我还注意到请求的Content-Length值不同,也相差大约33%。因此,不管出于什么原因,jQuery生成的POST请求实际上并没有以UTF-8发送?我遗漏了什么,这个难题的最后一块是什么?
2条答案
按热度按时间xuo3flqw1#
解决方案原来是使用Typed Arrays和XHR2的
FormData
(polyfill可用于两者,但两者目前都享有重要的原生支持)。wgxvkvu92#
您也可以在客户端对文件名进行编码,然后在服务器上对其进行解码。
服务器端(带有multer的Node.js)