A Problem and Solution of Using FormData Object to Implement File Upload Function of Form in tp3.2.3

Keywords: JQuery JSON PHP

The html code for the form is as follows:
<form name="addForm" id="addForm" action="__SELF__" method="post" enctype="multipart/form-data">
    Commodity logo: <input type="file" name="goods_logo"/>
    ...
    <input type= "submit" value= "submit" onclick= "testAjax ();"/>
</form> 

Because the above operations include uploading files, and ordinary ajax can not upload files, Baidu has two methods of using FormData object and plug-in. See the previous blog post for details, so I tried the method of FormData object.
Scenario: I want to use thinkPHP 3.2.3 framework to verify the validity of input data when adding goods, and then go to the front desk to prompt. At first, the jump prompt is realized through built-in jump function. It will jump to a page to display and then return. This gives people a bad visual experience. So I want to change it to Ajax mode to update data asynchronously without refreshing this page, and neither do I. Instead of leaving this page, alert pops up a warning box to prompt the user whether the input data is legitimate or not. Because the form data of goods contains files, the method of collecting data built in jquery is used in the beginning when using ajax: $("form").serialize(); but it does not support the collection of file data, so Baidu tried to use FormData and Ajax to achieve asynchronous submission of forms and upload files.
The first step is to modify the jump function when the controller executes successfully or unsuccessfully, such as

$this->success('Add success!',U('listGoods'),true);
$this->error('Failed to add!',U('add'),true);
Careful students should find that there is a difference from the previous writing, that is, an additional parameter is given, the default is false, set to true, indicating that the form is submitted using ajax, thus not performing a jump, but returning the data in json format as follows:

{"info":"\u6dfb\u52a0\u6210\u529f\uff01","status":1,"url":"\/shop\/index.php\/Admin\/Goods\/listGoods.html"}
{"info":"\u6dfb\u52a0\u6210\u529f\uff01","status":0,"url":"\/shop\/index.php\/Admin\/Goods\/listGoods.html"}
This allows data to be retrieved within the success callback function executed by the foreground ajax, with status=1 indicating success and status=0 indicating failure.

The method code used at the beginning is as follows:

         function testAjax(){
            var formData = new FormData(document.getElementById("addForm"));
            $.ajax({
                url:"__SELF__",
                type:"post",
                data:formData,
                dataType: 'json',
                processData:false,// Tell jQuery not to process the data sent
                contentType:false,// Tell jQuery not to set the Content-Type request header
                success:function(data){
                    window.clearInterval(timer);
                    console.log("over...");
                    //Determine whether the addition was successful
                    if(data.status == 1){
                        alert(data.info); 
                        location.href = data.url;
                    }
                    else{           
                        alert(data);
                    }
                    
                },
                error:function(e){
                    alert("error");
                    window.clearInterval(timer);
                }
            });
            get();//Here is the progress bar for uploading files     
        }
Normally it doesn't jump, but I guess it's the use of FormData objects that causes ajax to jump to a blank interface to display the returned json-formatted prompts after executing the callback function. This effect is obviously not what I want, so I began to test, see what went wrong, and finally found that it really can not control it. I suddenly found out at a loss that the onclick event is now used with the submission button. I guess that's the reason. It's okay to change it anyway, so I changed it to restrict the submission of forms through the button to achieve the results. If you don't jump on your own, you're really excited!! At this point, it is clear that the most critical reason should not be related to FormData, but actually the reason for the submission method.

The following is the method code that is normally implemented:

         $("form[name=addForm]").submit(function(){  //ok
            var formData = new FormData(document.getElementById("addForm"));
            $.ajax({
                url:"__SELF__",
                type:"post",
                data:formData,
                dataType: 'json', //Data type returned
                processData:false,// Tell jQuery not to process the data sent
                contentType:false,// Tell jQuery not to set the Content-Type request header
                success:function(data)//Callback function after ajax execution
                {
                    //Determine whether the addition was successful
                    if(data.status == 1){
                        alert(data.info);
                        location.href = data.url;
                    }
                    else{
                        alert(data.info);
                    }
                }
            });
            return false;//Prevent form submission
        });

In fact, the core code above is the same. The difference is that the first one binds the click event of the submit button to realize the asynchronous submission of form data, while the second one prevents the click submission function of the form button. I will not explain the specific reasons.

But fortunately, the problem has been solved smoothly. I hope the big man knows the internal reasons can explain a wave. Thank you!





Posted by stephanie on Fri, 24 May 2019 14:07:45 -0700