【问题标题】:Posting a form with file attachments using pjax (and jQuery.form?)使用 pjax(和 jQuery.form?)发布带有文件附件的表单
【发布时间】:2012-12-04 15:38:23
【问题描述】:

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

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

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

【问题讨论】:

  • 您可以尝试用JS将数据转换为Base64String并作为文件发布,然后在帖子中您可以将其转换为字节数组并将文件与数组一起保存。
  • IE

标签: jquery pjax


【解决方案1】:

您可能需要在可以处理文件的 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 元素进行上传,因为 FormData 仅在 Internet Explorer 10 中受支持。用于提交文件的出色插件我已经测试并在没有 jQuery 的情况下工作是 http://fineuploader.com/,我认为它比 https://github.com/malsup/form(jquery.form 插件)更好/更容易使用。

【讨论】:

  • jasdeepkhalsa,感谢您的精心回复!但不幸的是,它并没有解决我的问题,因为 that 浏览器 (MSIE) 无法使用 FormData 对象。这就是我尝试使用 jquery.form 插件的原因。它有一些 iframe 魔法的解决方法。
  • @mawimawi - 我明白了,谢谢你的澄清。我认为我发布的插件应该可以解决您的问题!
  • 不幸的是,我无法找到将 FineUploader、jQuery.form 或 Uploadify 集成到 pjax 中的方法。如果它有文件输入字段,我需要一种方法来告诉 pjax 正确处理表单。执行两个单独的 HTTP 请求并不是一个真正的选择,因为我的服务器脚本会发送回表单(发生错误时)或其他一些成功页面。 (我希望我没有让你感到困惑......)
  • @mawimawi - 首先,我认为您根本没有明确说明您的问题 - 请在您的问题中明确说明(a)您的代码当前看起来像客户端和服务器端(b ) 您当前正在使用哪种 pjax 解决方案 (c) 您的服务器发送回的数据和第四个数据。其次,直到 Internet Explorer 10 才支持 pushState,所以我不知道您希望如何在 IE 中实现与 pjax 的“集成”?
  • 虽然我的问题仍然没有解决办法,但时间已经不多了,所以我不得不决定给谁赏金。感谢你付出的努力。他们真的很感激。还要感谢 Faraz、Dasun 和 Dean。
【解决方案2】:

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 在服务器级别上传文件。

如果你想在插件中拥有这个功能,你可以用上面的代码扩展插件,它不会让你的插件变砖,因为这是一个非常简单的代码 sn-p 可以完成工作。我已经成功地将代码集成到插件中,没有任何问题。

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

【讨论】:

  • 嗯。我在这里看不到任何 pjax-y 行为。我希望 pjax 和文件上传只需一个电话就可以连接在一起。我真的不想暂时保存一些东西等。只需一张表格和一张 pjax-y 提交。就像任何其他 pjax 形式一样。
  • 据我所知,无法上传 Ajax 文件,但使用上述方法可以完成。
【解决方案3】:

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

【讨论】:

  • 是的,我知道。但我希望 pjax 和文件上传只需一个电话就可以连接在一起。我真的不想暂时保存一些东西等。只需一张表格和一张 pjax-y 提交。就像任何其他 pjax 形式一样。
【解决方案4】:

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

【讨论】:

  • 你让我很好奇。什么是 EXT?
  • sencha.com/products/extjs 是一个javascript框架,我觉得几年前还挺火的。
猜你喜欢
  • 2017-11-08
  • 2014-12-27
  • 2015-03-13
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 2014-05-02
相关资源
最近更新 更多