为什么 AJAX 输出带有错误的编码
Why does AJAX output comes with wrong encoding?
>我正在使用AJAX(Angular)从服务器获取文件。该文件是一个简单的XLSX document
,发送方式如下:
ob_start();
$file = 'PHPExcel_IOFactory::createWriter($xls, 'Excel2007');
$file->save('php://output');
$response->setContent(ob_get_clean());
$response->headers->replace(array(
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'Content-Disposition' => 'attachment;filename=file.xlsx"'
));
当我从前端发出请求时,我也使用接受标头。然后我使用 FileSaver.js 和 Blob.js 使用角度文件保护程序保存文件。但是收到的文件已损坏,我无法在Excel中打开它:它的大小(例如)为12446字节,但Chrome的DevTools Network选项卡将响应内容长度标头显示为7141字节。
如何解决这个问题?
上级:我发送这样的请求:
$http.get(baseURL + '/' + entity + '/export/?' + condition + sort, {
headers: {'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8'}
});
并像这样下载文件:
var data = new Blob([response.data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'});
FileSaver.saveAs(data, 'file.xlsx');
我解决这个问题的方法是使用普通的 JS AJAX,而不是 AngularJS。(AngularJS和JQuery处理二进制响应可能存在问题。
这应该有效:
var request = new XMLHttpRequest();
request.open('GET', 'http://yourserver/yourpath', true);
request.responseType = 'blob';
request.onload = function (e) {
if (this.status === 200) {
var blob = this.response;
if (window.navigator.msSaveOrOpenBlob) {
var fileNamePattern = /filename[^;='n]*=((['"]).*?'2|[^;'n]*)/;
window.navigator.msSaveBlob(blob, fileNamePattern.exec(request.getResponseHeader("content-disposition"))[1]);
} else {
var downloadLink = window.document.createElement('a');
var contentTypeHeader = request.getResponseHeader("Content-Type");
var b = new Blob([blob], { type: contentTypeHeader });
downloadLink.href = window.URL.createObjectURL(b);
var fileNamePattern = /filename[^;='n]*=((['"]).*?'2|[^;'n]*)/;
downloadLink.download = fileNamePattern.exec(request.getResponseHeader("content-disposition"))[1];
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
window.URL.revokeObjectURL(b);
}
}
};
request.send();
代码基于这个和这个。
仅供参考,我发现当response.data
不是作为blob
返回而是text/plain
或application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
时,new Blob([response.data], ...)
返回的大小几乎是response.data
大小的两倍。要绕过它,您需要向它传递一个字节数组:
var i, l, d, array;
d = this.result;
l = d.length;
array = new Uint8Array(l);
for (var i = 0; i < l; i++){
array[i] = d.charCodeAt(i);
}
var b = new Blob([array], {type: 'application/octet-stream'});
window.location.href = URL.createObjectURL(b);
代码来自这里。
无论如何,由于使用AngularJS的AJAX响应不正确,因此您将无法以这种方式获得有效的xlsx文件。你需要使用香草JS。
相关文章:
- 回复'js'仅当请求有错误时(否则使用html)
- 我不知道我的编码有什么问题.(JavaScript)
- 表单已发送,但验证有错误
- 如果文件不存在,fs.watch是否有错误处理程序
- Meteor上有错误的同步问题
- 表单验证:如果有错误,不要't使手风琴动起来
- 我有错误文档.注册元素未被细化
- 如何转换为特定于 json 的类 c#?我有错误
- 如果当前输入有错误或警告,则禁用所有下一个表单输入字段
- 通过有错误的 Ajax-Request 打印出 HTML 会阻止进一步的 JS 工作
- 脸书应用程序有错误
- XDomainRequest 总是有错误
- HTML5 Canvas游戏有错误,点击时第一个拼图块会变成不同的块
- 科尔多瓦反向地理编码返回错误
- Page_ClientValidate返回 false,但没有一个验证器有错误
- 量角器由中继器命令中是否有错误
- Jquery 验证器 - 表单被保存但有错误
- 任何人看到我的重置功能有错误
- XML标记有错误的编码
- asp.net mvc 3-发送给javascript的字符串中有错误的文本编码