ete*_*ode 0 javascript jquery post utf-8
在我开始之前:这是一个100%的客户端问题.忘记服务器端语言,我如何处理上传等等 - 我正在比较一个已知的工作HTTP文件上传请求和jQuery生成的AJAX请求,理论上应该做同样的事情.
背景:我正在为tinyMCE编写一个文件上传插件.部分内容涉及允许支持它的浏览器上传拖放图像 - 具体来说,当文件系统映像被放入tinyMCE编辑器时,firefox中的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
}
});
Run Code Online (Sandbox Code Playgroud)
同样容易地准备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 + '--'
;
Run Code Online (Sandbox Code Playgroud)
剩下的就是把它发送到服务器:
$.ajax({
type: 'POST',
url: '/upload/',
contentType: 'multipart/form-data; boundary=' + boundary.slice(2),
data: data
});
Run Code Online (Sandbox Code Playgroud)
服务器"正确"处理POST(它看到文件并将其保存到磁盘上),但是生成的图像已经完全损坏 - 它不会在浏览器中显示,而且它的jpeg头完全错误,而不是提到它比本地大33%(服务器上12K比本地9K).
使用Firebug的Net选项卡,没有任何错误 - 实际上,除了charset=UTF-8Content-Type请求标头中的额外内容以及缺乏漂亮打印的POST数据之外,此AJAX请求看起来与相应的表单POST 完全相同.但是,使用HttpFox讲述了一个不同的故事:
表格上传:
-----------------------------191891488320550623041315726177
Content-Disposition: form-data; name="file-upload"; filename="file.jpg"
Content-Type: image/jpeg
ÿØÿàJFIFHHÿÛC...
Run Code Online (Sandbox Code Playgroud)
ajax上传:
--------------------boundary1375846064929
Content-Disposition: form-data; name="file-upload"; filename="file.jpeg"
Content-Type: image/jpeg
ÿÃÿà JFIFHHÿÃC...
Run Code Online (Sandbox Code Playgroud)
我还注意到请求Content-Length值不同,再次约为33%.所以看来,无论出于何种原因,jQuery生成的POST请求实际上都不会以UTF-8发送?我错过了什么,这个难题的最后一部分是什么?
解决方案原来是使用Typed Arrays和XHR2 FormData(polyfills 可用于两者,但两者目前都享有重要的原生支持).
images.each(function(){
var image = this,
data = /data:(image\/\w+);base64,(.*)/gmi.exec(this.src),
format, ext, binary;
if (data){
format = data[1];
ext = format.split('/')[1];
binary = atob(data[2]);
data = new Uint8Array(binary.length);
for (var i=0; i<binary.length; i++)
data[i] = binary.charCodeAt(i);
}
else {
// blah, not supported
}
var fd = new FormData();
fd.append('file-upload', new Blob([data], {type: format}), 'uploaded_image.' + ext);
$.ajax({
type: 'POST',
url: '/upload/',
data: fd,
processData: false,
contentType: false
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3873 次 |
| 最近记录: |