Javascript 使用FormData';在不受支持的浏览器上的blob对象上的s append方法
在为用户上传的图像创建Ajax请求时,我以以下方式使用Javascript 使用FormData';在不受支持的浏览器上的blob对象上的s append方法,javascript,Javascript,在为用户上传的图像创建Ajax请求时,我以以下方式使用FormData()实例: var form_data = new FormData(); form_data.append(img_field, img_to_send, img_name); 请注意,img\u to\u send是类型为Blob的对象 我的问题是以下浏览器兼容性小警告: Android 4.0中的XHR为带有blob的FormData发送空内容 这与Android浏览器(4.0版)有关。这意味着我尝试通过append使
FormData()
实例:
var form_data = new FormData();
form_data.append(img_field, img_to_send, img_name);
请注意,img\u to\u send
是类型为Blob
的对象
我的问题是以下浏览器兼容性小警告:
Android 4.0中的XHR为带有blob的FormData发送空内容
这与Android浏览器(4.0版)有关。这意味着我尝试通过append
使用FormData
的xhr可能会在该特定浏览器中失败
我的问题是,我可以使用什么样的替代方案来确保所述浏览器能够正确处理xhr(我的一项要求)?有一个说明性的例子就好了
如果这里没有其他选择,我如何编写代码,使其仅在支持append
和blob
对象的浏览器中执行?像这样的
if (window.FormData.append) {
// xhr code comes here
}
那件事我很不确定
p、 为了回答这个问题,请坚持使用纯JS。。。。这不是一件容易的事 我要问自己的第一个问题是,我是否真的必须支持这个7年的浏览器,并且使用率为0% 功能检测: 我们现在可以通过
get()
,has()
,entries()
,values()
等方法检查FormData包含的内容。但是第一个规范和实现没有这些方法,因此没有提供任何方法来检测这个特定的流
我没有这样的Android 4浏览器要检查,但我猜他们也没有这些方法
另一种现代的有点黑客的检查方法是使用ServiceWorker,它应该能够拦截一个虚拟请求,让你知道你的Blob是否附加得很好,但7年前ServiceWorkers还是不存在的
这给我们留下了一个丑陋的浏览器标识,而不是一个功能检测(例如navigator.userAgent
parsing)。我不能建议您这样做,因为这样做很容易出错,所以最好让您的用户知道它在服务器响应中失败了
解决方法
这个功能在几个月前才出现,目前只有Blink浏览器在本机上支持它,并且通过一个bug漏洞进行FF攻击
这意味着,对于Android Browser 4.xxx上的用户和所有不支持此方法的浏览器,唯一的解决方法是将生成的Blob保存在设备上,然后从
中选取并通过普通HTML
发送,但这是假设他们甚至可以在他们的设备上保存这个斑点,我不能确定
或者你也可以发送一个大30%的base64数据表示
或者,最好是让他们知道他们应该更新他们的浏览器,因为现在面对网络使用这么旧的浏览器真的很危险
因此,我们简要回顾一下不那么糟糕的可能性:
您好,这是一个小例子,如何将文件作为二进制字符串发送到服务器。 这样您就不需要formData了。你可以用简单的邮件发送。 请将url uploadFile.php更改为您的url。并阅读服务器应该接收的关于变量示例的注释
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
<input id="btnFile" type="file" accept="image/*" />
</div>
<div style="margin-top: 20px; width: 100px; border: solid 1px red">
<div id="divProgress" style="background-color: red;width: 10px; height: 5px; margin: 1px"></div>
</div>
<div style="margin-top: 20px">
<input id="btnSend" type="button" value="Send File" />
<input id= "user_id" type="hidden" value="123"/>
</div>
<script>
var btnFile = document.getElementById("btnFile");
var btnSend = document.getElementById("btnSend");
var divProgress = document.getElementById("divProgress");
var selectedFile = null;
//Register event on file selected or changed.
addEvents(btnFile, "change", function (event) {
if (event.target.files.length !== 0) {
var file = event.target.files[0];
//Check if the file is IMAGE.
if (file.type.match("image.*")) {
selectedFile = file;
} else {
selectedFile = null;
alert("Please select a IMAGE FILE");
}
} else {
selectedFile = null;
}
});
//EVENT BTN SEND.
addEvents(btnSend, "click", function () {
if (selectedFile === null) {
//Please select a file to upload.
alert("Please select the file.");
return;
}
//File reader object.
var fl = new FileReader();
//Add event to read the content file.
addEvents(fl, "load", function (evt) {
//alert(evt.target.result);
try {
//CONVERT ARRAY BUFFER TO BASE64 STRING.
var binaryString = evt.target.result;
//NOW YOU CAN SEND SIMPLE POST DATA.
var xhr = new XMLHttpRequest();
if (supportProgress(xhr)) {
addEvents(xhr, "progress", onXHRProgress);
addEvents(xhr, "loadstart", onXHRLoadStart);
addEvents(xhr, "abort", onXHRAbort);
}
xhr.open("POST", "/uploadFile.php", true);
//xhr.setRequestHeader("Content-Type", "application/json");
var user_id = document.getElementById('user_id').value;
var myData = {
uid: user_id,
fileName: selectedFile.name,
mimeType: selectedFile.type,
extension: getFileExtension(selectedFile),
contentFile: binaryString
};
xhr.send(JSON.stringify(myData));
/*
* IN YOUR SERVER SIDE YOU GET THE POST VARIABLE.
* fileName = The name of the file.
* mimeType = example "image/png"
* extension = png
* conentFile = Binary String of the content file and you can convert the Binary String to File in your disk according extension or mimeType
*/
} catch (e) {
}
});
//Read the file as arraybuffer.
fl.readAsBinaryString(selectedFile);
});
function onXHRProgress(e) {
var loaded = 0;
if (e.lengthComputable) {
if (e.loaded === e.total) {
loaded = 100;
selectedFile = null;
} else {
loaded = Math.round((e.loaded * 100) / e.total);
}
//Change the progress here.
divProgress.style.width = loaded + "px";
}
}
function onXHRLoadStart() {
divProgress.style.width = "0px";
}
function onXHRAbort() {
selectedFile = null;
}
function getFileExtension(file) {
var fileName = file.name;
var i = fileName.toString().lastIndexOf(".");
if (i !== -1) {
return fileName.toString().substring((i + 1), fileName.toString().length).toLowerCase();
} else {
return "";
}
}
function supportProgress(xhr) {
return !!(xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
}
function addEvents(obj, evtName, func) {
if (obj.addEventListener !== undefined && obj.addEventListener !== null) {
obj.addEventListener(evtName, func, false);
} else if (obj.attachEvent !== undefined && obj.attachEvent !== null) {
obj.attachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = func;
} else {
obj[evtName] = func;
}
}
}
function removeEvents(obj, evtName, func) {
if (obj.removeEventListener !== undefined && obj.removeEventListener !== null) {
obj.removeEventListener(evtName, func, false);
} else if (obj.detachEvent !== undefined && obj.detachEvent !== null) {
obj.detachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = null;
} else {
obj[evtName] = null;
}
}
}
</script>
</body>
</html>
提供头衔
var btnFile=document.getElementById(“btnFile”);
var btnSend=document.getElementById(“btnSend”);
var divProgress=document.getElementById(“divProgress”);
var selectedFile=null;
//在选定或更改的文件上注册事件。
addEvents(BTN文件,“更改”、函数(事件){
如果(event.target.files.length!==0){
var file=event.target.files[0];
//检查文件是否为图像。
if(file.type.match(“image.*)){
selectedFile=file;
}否则{
selectedFile=null;
警报(“请选择图像文件”);
}
}否则{
selectedFile=null;
}
});
//事件BTN发送。
附录(BTN发送,“单击”,函数(){
如果(selectedFile==null){
//请选择要上载的文件。
警报(“请选择文件”);
返回;
}
//文件读取器对象。
var fl=新文件读取器();
//添加事件以读取内容文件。
加法器(fl,“负载”,功能(evt){
//警报(evt.target.result);
试一试{
//将数组缓冲区转换为BASE64字符串。
var binaryString=evt.target.result;
//现在您可以发送简单的POST数据。
var xhr=new XMLHttpRequest();
if(支持进度(xhr)){
附录(xhr,“进度”,onXHRProgress);
附录(xhr,“加载启动”,ON XHRLOADSTART);
附录(xhr,“中止”,onXHRAbort);