Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用FormData';在不受支持的浏览器上的blob对象上的s append方法_Javascript - Fatal编程技术网

Javascript 使用FormData';在不受支持的浏览器上的blob对象上的s append方法

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使

在为用户上传的图像创建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
的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是否可用。否则,退回到
  • 第一次以多部分的形式发送最佳Blob
  • 在服务器上:检查收到的Blob是否为空。在这种情况下,通过自定义响应让前端知道
  • 若服务器说它失败了,那个么再次发送,这次是b64。因为第一次是空的,所以无论如何,它不应该是一个太重的请求

  • 您好,这是一个小例子,如何将文件作为二进制字符串发送到服务器。 这样您就不需要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);