使用pjax(和jQuery.form?)发布带有文件附件的表单

时间:2012-12-17 14:21:03

标签: jquery pjax

我成功地将pjax用于链接和表单(GET以及POST)。但现在我有一个表格,也必须发送<input type="file"...>。由于pjax不支持这一点,我查看了https://github.com/malsup/form(jquery.form插件) 支持使用文件提交表单数据,但不在&#34; pjax&#34中;使用浏览器历史记录对象的方法。

那么,如何在包含文件字段的表单中使用pjax功能呢?有什么想法吗?

编辑:我之所以不简单地使用FormData对象,而是使用jquery.form插件:Internet Explorer无法处理它们。该插件为此浏览器提供了一种解决方法。我不坚持使用jquery.form插件,但我需要一种方法使其适用于所有主流浏览器。

4 个答案:

答案 0 :(得分:5)

似乎您可能需要在AJAX / pJAX请求中使用FormData对象来处理文件。您可以在Mozilla Developer Network上了解更多信息。

例如,如果这是您的表单:

<form enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>

首先获取文件内容如下:

var formData = new FormData($('form')[0]);

然后您可以使用jQuery $.ajax请求或简单的XMLHttpRequest();,如下所示:

var xhr = new XMLHttpRequest();
xhr.open("POST", "http://foo.com/processfile.php");
xhr.send(formData);

或类似的jQuery:

$.ajax({
    url: 'http://foo.com/processfile.php',
    type: 'POST',
    data: formData,
    cache: false,
    contentType: false,
    processData: false
});

在服务器端,在processfile.php中,您可以使用以下方式接收/显示文件内容:

$file = $_FILES['file']['name'];

这应该与pJAX一起使用,因为它是异步的!只需确保在pJAX请求之前发出此请求,或者如果您使用的是jQuery,则可以将其添加为成功回调的一部分。例如(不知道您正在使用哪个pJAX库):

$.ajax({
    url: 'http://foo.com/processfile.php',
    type: 'POST',
    data: formData,
    cache: false,
    contentType: false,
    processData: false,
    success: function(data) {
       $.pjax({url: url, container: '#pjax-container'});
    }
});

编辑:如果您想支持IE7 +,则需要回退使用隐藏的iframe元素进行上传,因为仅在Internet Explorer 10中支持FormData。这是一个用于提交文件的绝佳插件我已经测试并且在没有jQuery的情况下工作http://fineuploader.com/在我看来比https://github.com/malsup/form(jquery.form插件)更好/更容易使用。

答案 1 :(得分:1)

jQuery Ajax代码

jQuery('document').ready(function(){

    var input = document.getElementById("imagefile");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }

    input.addEventListener("change", function (evt) {

        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            //validation to check whether uploaded files are images
            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) { 
                    };
                    reader.readAsDataURL(file);
                }


                if (formdata) {
                    //send the ajax query to upload the file(s)
                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (result) {
                            jQuery('div#response').html("Successfully uploaded").fadeOut();
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }   
        }

    }, false);


});

HTML代码

<form enctype="multipart/form-data">
<input id="imagefile" type="file" name="image" accept="image/*"/ />
</form>

以上代码将为您做的是,一旦您上传文件,它将首先验证图像的类型并通过ajax为您上传。如果需要,您可以执行多个文件上传。如果您想知道FormData做了什么,

  

FormData对象允许您编译一组键/值对   使用XMLHttpRequest发送。它主要用于发送   表单数据,但可以独立于表单使用   传输密钥数据。传输的数据格式相同   表单的submit()方法将用于发送表单中的数据   编码类型设置为“multipart / form-data”。

addEventListener为您做的是,

  

addEventListener()在单个事件上注册单个事件侦听器   目标。事件目标可以是文档中的单个元素,   文档本身,窗口或XMLHttpRequest。

您可以使用upload.php在服务器级别上传文件。

如果你想在插件中使用这个功能,你可以使用上面的代码扩展插件,它不会破坏你的插件,因为这是一个非常直接的代码片段,可以完成工作。我已经成功地将代码集成到一个插件中而没有任何问题。

如果您有任何问题,请告诉我。

答案 2 :(得分:0)

您可以单独使用uploadify进行文件上传,并在其回调函数中使用上传的文件路径更新表单,或者只需将上传状态设置为true或false,当您提交表单时,可以从uploadify temp文件夹访问该文件并根据这一点做出回应。

答案 3 :(得分:0)

这样做的一种方法是,当您发现表单中有文件上传时,在页面上构建隐藏的iframe以及其中的整个表单,然后在iframe中提交表单。您还需要在'load'事件上向iframe添加一个侦听器,因此当submit返回时,您可以处理响应。这就是EXT如何处理这种情况。