7

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

那么,如何将 pjax 功能与包含文件字段的表单一起使用呢?有任何想法吗?

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

4

4 回答 4

5

似乎您可能需要FormData在 AJAX/pJAX 请求中使用可以处理文件的对象。您可以在Mozilla 开发者网络上阅读更多内容。

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

<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 元素进行上传,因为 FormData 仅在 Internet Explorer 10 中受支持。我已经测试过且无需 jQuery 即可提交文件的一个很棒的插件是http: //fineuploader.com/在我看来比https://github.com/malsup/form(jquery.form 插件)更好/更容易使用。

于 2012-12-19T16:06:11.923 回答
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 发送。它主要用于发送表单数据,但可以独立于表单使用以传输键控数据。如果表单的编码类型设置为“multipart/form-data”,则传输的数据与表单的 submit() 方法用于发送数据的格式相同。

addEventListener 为您做的是,

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

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

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

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

于 2012-12-21T02:02:44.617 回答
0

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

于 2012-12-20T10:19:02.117 回答
0

这样做的一种方法是,当您发现表单中有文件上传时,在页面上构建一个隐藏的 iframe,连同其中的整个表单,然后在 iframe 中提交表单。此外,您需要在 iframe 的“加载”事件上添加一个侦听器,以便在提交返回时,您可以处理响应。这就是 EXT 处理这种情况的方式。

于 2012-12-25T10:07:34.710 回答