jQuery 表单插件:enctype:multipart/form-data 和文件上传 - 没有 JSON 返回?

发布于 2025-01-08 03:16:17 字数 1775 浏览 1 评论 0原文

奇怪的问题或错误。我正在使用 jQuery 表单插件,它在任何地方都可以正常工作,在我有一个表单的地方接受在表单上使用 enctype:multipart/form-data 进行文件上传。在此表单上,我面临两个奇怪的事情……

  1. 从服务器返回的 JSON 对象是空的!
  2. 在 Opera 中,提交按钮甚至会触发文件下载!

但是,只有当我在表单中保留 enctype:multipart/form-datainput type="file" 时,才会发生这种情况。没有它,一切都会正常工作,并且 JSON 对象会正确返回 - 并且 Opera 中无法下载。

HTML:

<form accept-charset="UTF-8" action="/ajax/profiledetails" id="profileAboutMeForm" method="post" novalidate="novalidate" encoding="multipart/form-data" enctype="multipart/form-data">

    ...

    <p class="rel avatarUpload">
        <label class="label" for="profileAvatar">Choose Avatar</label>
        <img class="profileAvatar avatar30" src="" alt="user">
        <input class="fileUpload br3" id="profileAvatar" name="profile[avatar]" type="file">
    </p>

    ...

</form>

jQuery:

$(formId).ajaxSubmit({
        type: "POST",
        cache: false,
        resetForm: reset,
        dataType: "text json",
        success: function(jsonObject, status) {

            console.log("status + ", jsonObject.status: "+ jsonObject.status + ", jsonObject.data: " + jsonObject.data);

知道什么可能导致这种情况吗?我该如何解决这个问题?

提前致谢。

编辑:

但我从未尝试过只是记录对象本身,事实证明,在这种情况下(仅当设置了文件输入和 enctype 时) jsonObject 是一个 STRING 而不是一个目的。

if (typeof jsonObject == 'string')
        console.log('yes, it's a string'); //yes, it's a string
        jsonObject = JSON.parse(jsonObject);

console.log(jsonObject);

所以,这意味着我的 javascript 中再次有了一个 JSObject,这解决了我的第一个问题,但是 opera-bug 仍然存在!有什么想法吗?

weird problem or bug. I'm using the jQuery Form Plugin and it works fine everywhere accept on one form where I have a single file-upload with enctype:multipart/form-data on the form. On this form I'm facing two weird things …

  1. the JSON object that is returned from the server is empty!
  2. In Opera the Submit-button even triggers a file-download!

However this occurs only if I leave the enctype:multipart/form-data and the input type="file" in the form. Without it everything works fine and the JSON Object is returned correctly - and there is no download in Opera.

HTML:

<form accept-charset="UTF-8" action="/ajax/profiledetails" id="profileAboutMeForm" method="post" novalidate="novalidate" encoding="multipart/form-data" enctype="multipart/form-data">

    ...

    <p class="rel avatarUpload">
        <label class="label" for="profileAvatar">Choose Avatar</label>
        <img class="profileAvatar avatar30" src="" alt="user">
        <input class="fileUpload br3" id="profileAvatar" name="profile[avatar]" type="file">
    </p>

    ...

</form>

jQuery:

$(formId).ajaxSubmit({
        type: "POST",
        cache: false,
        resetForm: reset,
        dataType: "text json",
        success: function(jsonObject, status) {

            console.log("status + ", jsonObject.status: "+ jsonObject.status + ", jsonObject.data: " + jsonObject.data);

Any idea what could cause that? How I could fix that?

Thank's in advance.

edit:

What I never tried though was to just log the object itself and here it turns out that in this case (only if the file-input and enctype is set) the jsonObject is a STRING and not an object.

if (typeof jsonObject == 'string')
        console.log('yes, it's a string'); //yes, it's a string
        jsonObject = JSON.parse(jsonObject);

console.log(jsonObject);

So, this means I have a JSObject again in my javascript and this fixes my first problem, however the opera-bug still remains! Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

短叹 2025-01-15 03:16:17

作为一个起点,我假设您已经阅读了插件页面上有关此内容的文档 http ://jquery.malsup.com/form/#file-upload?您无法访问 ajaxSubmit() 中的 JSON,因为响应实际上写入到用于上传的隐藏 iframe 中。

“由于无法使用浏览器上传文件
XMLHttpRequest 对象,表单插件使用隐藏的 iframe 元素来
帮助完成任务。这是一种常见的技术,但它有其固有的特点
限制。 iframe 元素用作表单的目标
提交操作意味着服务器响应被写入
iframe。如果响应类型是 HTML 或 XML,这没问题,但是
如果响应类型是脚本或 JSON,则效果不佳
其中通常包含需要使用实体来表示的字符
在 HTML 标记中找到引用。

为了解决脚本和 JSON 响应的挑战,表单
插件允许将这些响应嵌入到文本区域元素中
建议您在使用这些响应类型时这样做
与文件上传结合。但请注意,如果有
表单中没有文件输入则请求使用普通 XHR 提交
表单(不是 iframe)。这会给您的服务器代码带来负担
知道何时使用文本区域,何时不使用。如果你喜欢,你可以使用
插件的 iframe 选项强制其始终使用 iframe
模式,然后您的服务器始终可以将响应嵌入到文本区域中。”

这是他在示例页面上使用的代码:

$('#uploadForm').ajaxForm({
  beforeSubmit: function(a,f,o) {
    o.dataType = $('#uploadResponseType')[0].value;
    $('#uploadOutput').html('Submitting...');
  },
  success: function(data) {
    var $out = $('#uploadOutput');
    $out.html('Form success handler received: <strong>' + typeof data + '</strong>');
    if (typeof data == 'object' && data.nodeType)
      data = elementToString(data.documentElement, true);
    else if (typeof data == 'object')
      data = objToString(data);
    $out.append('<div><pre>'+ data +'</pre></div>');
  }
});

success 方法在这里对您来说很重要...请注意,他正在编写将数据返回到页面以进行调试。

Just as a starting point, I assume you've read the documentation about this on the plugins page at http://jquery.malsup.com/form/#file-upload? You won't get access to the JSON within ajaxSubmit() because the response is actually written to a hidden iframe used for the upload.

"Since it is not possible to upload files using the browser's
XMLHttpRequest object, the Form Plugin uses a hidden iframe element to
help with the task. This is a common technique, but it has inherent
limitations. The iframe element is used as the target of the form's
submit operation which means that the server response is written to
the iframe. This is fine if the response type is HTML or XML, but
doesn't work as well if the response type is script or JSON, both of
which often contain characters that need to be repesented using entity
references when found in HTML markup.

To account for the challenges of script and JSON responses, the Form
Plugin allows these responses to be embedded in a textarea element and
it is recommended that you do so for these response types when used in
conjuction with file uploads. Please note, however, that if there is
no file input in the form then the request uses normal XHR to submit
the form (not an iframe). This puts the burden on your server code to
know when to use a textarea and when not to. If you like, you can use
the iframe option of the plugin to force it to always use an iframe
mode and then your server can always embed the response in a textarea."

Here is the code he uses on the examples page:

$('#uploadForm').ajaxForm({
  beforeSubmit: function(a,f,o) {
    o.dataType = $('#uploadResponseType')[0].value;
    $('#uploadOutput').html('Submitting...');
  },
  success: function(data) {
    var $out = $('#uploadOutput');
    $out.html('Form success handler received: <strong>' + typeof data + '</strong>');
    if (typeof data == 'object' && data.nodeType)
      data = elementToString(data.documentElement, true);
    else if (typeof data == 'object')
      data = objToString(data);
    $out.append('<div><pre>'+ data +'</pre></div>');
  }
});

The success method is what matters for you here...notice that he is writing the return data to the page for debugging purposes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文