JQuery表单插件文件上传使用POST重定向到POST响应

时间:2013-12-22 12:55:42

标签: jquery post jquery-forms-plugin

请帮帮我们,这个是一个主要的BLOCKER!

我有一个使用NodeJS + jQuery Form Plugin + Typescript的项目,我正在尝试上传文件。文件上传后,服务器会向POST消息发送响应,该消息在屏幕上呈现。在POST响应呈现在屏幕上之前,文件确实已成功上传。我希望POST响应调用“成功”函数,而不是重定向页面以显示JSON响应。

以下是代码:

$(new ID().setAsRoot().selectId()).append(
    "<form id=\"fileUploadForm\" accept-charset=\"utf-8\" method=\"post\" action=\"/upload\" enctype=\"multipart/form-data\">" +
        "<input id = \"filename\" type=\"file\" name=\"userfile\" multiple=\"multiple\" />" +
        "<button type=\"submit\" id = \"submitButton\"> Upload </button></form>");

var form = $("#fileUploadForm");
form.submit(function (e) {
    //e.preventDefault();
    this.ajaxSubmit({
        type: form.attr('method'),
        url: form.attr('action'),
        data: form.serialize(),
        success: function (data) {
            var x = JSON.parse(data);
            alert("Success : " + x);
        },
        error: function (data) {
            var x = JSON.parse(data);
            alert("Error : " + x);
        }
    });
});

不会调用成功函数(这意味着警报消息不会显示)。 JSON数据只是在屏幕上呈现如下:

{
  "path": "data\\cb3409f1cc234ec3f64b60d80be13a3e.html",
  "name": "feed.html"
}

控制台上出现错误:

Uncaught SyntaxError: Unexpected token : shortcut_manager.js:123
(anonymous function) shortcut_manager.js:123
(anonymous function) extensions::messaging:327
Event.dispatchToListener extensions::event_bindings:386
Event.dispatch_ extensions::event_bindings:371
Event.dispatch extensions::event_bindings:392
dispatchOnMessage

这是处理它的服务器端代码。服务器使用NodeJS强大的模块。

public upload(req:express.Request, res) {

        var form = new formidable.IncomingForm();
        var originalFileName:String;
        var filePath:String;
        form.uploadDir = this.directory;
        form.keepExtensions = true;
        form.type = 'multipart';
        var fields = [];
        form
            .on("error", function (err) {
            })
            .on("field", function (field, value) {
            })
            .on("end", function () {
                res.send({
                    path: filePath,
                    name: originalFileName
                });
            })
            .on("file", function (name, file:formidable.File) {
                originalFileName = file.name;
                filePath = file.path;
            });
        form.parse(req);
        return;
    }

- 更新 -

如果我$.ajax代替this.ajax。该文件无法上传。浏览器控制台显示错误:

XMLHttpRequest cannot load http://localhost/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. 

5 个答案:

答案 0 :(得分:1)

根据您的评论:

“感谢您的建议。$ .ajax根本不加载。它显示了您可能知道的错误。虽然您的怀疑是正确的,因为,当我使用”this.ajax“时,文件会上传但是控制台显示错误“类型没有方法ajax”

  • 您无法使用$.ajax()上传文件,方法与上传表单数据的方式相同。
  • 由于使用this.ajax时出现错误,表单会被提交。这就是您在浏览器中看到JSON响应的原因。

问题是this.ajax来自哪里?您是否从使用未包含的库的示例中复制了代码?

为了通过AJAX上传文件,你需要一些插件(自己做一些努力,特别是如果你需要支持旧浏览器)。

更新

提交处理程序应如下所示:

form.submit(function (e) {
  e.preventDefault();
  $(this).ajaxSubmit().done(function (data) {
    var x = JSON.parse(data);
    alert("Success : " + x);
  }).fail(function (data) {
    var x = JSON.parse(data);
    alert("Error : " + x);
  });
});

说明:由于你想调用一个jQuery插件,你需要一个jQuery对象,因此$(this)ajaxSubmit()不需要任何参数(如果需要,可以传入选项)。因为我没有传入参数,所以附加了回调,在本例中是donefail(而不是successerror)。

答案 1 :(得分:0)

将this.ajax(“http:// ...”)替换为url:form.attr('method')

  var form = $("#fileUploadForm");     
  $.ajax({
      type:form.attr('method'),
       url:form.attr('action'),
      data:form.serialize(),
             success: function(data){
      }});

答案 2 :(得分:0)

你问我为什么会收到错误:

  

XMLHttpRequest无法加载localhost /。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许原点'localhost:8080'访问。

如果是这样,那么你在localhost服务器上需要的东西(假设它也是Node)是来自localhost的响应的标头集,允许localhost:8080的Origin访问这个资源,如下所示:

res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080');

或许您实际上是尝试从同一台服务器请求但忘记8080是您的测试服务器:如果是,那么在您的测试中,您应该将您的URL列为

$.ajax("http://localhost:8080", { //....

或重复当前原点:

$.ajax( window.location.origin,{ // ....

你避免这种情况的最后一种选择(如果你不能在响应上设置Origin策略)是使用jsonp服务,该服务不太严格但功能较少,但这不适合你的任务,所以我不会进入那个。

无论哪种方式,一旦你超越了原始政策,你会遇到其他障碍,如@zeroflagL所提及的那样。这是一种可能适合您的方法:How to handle cross domain iframe file upload json response?

答案 3 :(得分:0)

我认为您的客户端代码存在几个不同的问题。

我看到您定义$form,但我从未看到您定义form的位置。然后,您致电form.attr(...)。除非你在其他地方定义了form,否则会立即抛出错误。

更重要的是,标准$.ajax()无法在较旧的浏览器上上传文件(即使最近的IE 9也是如此!)XHR2中添加了执行XHR文件上传的功能(请参阅CanIUse)。如果您希望您的Web应用程序与任何低级浏览器兼容,则需要以某种方式解决此限制。

好消息是有各种各样的插件可以为您完成大部分工作。如果您使用的jQuery版本大于1.6,我建议您查看jQuery File Upload Plugin。它在可用时使用新的XHR文件上载功能,并在不支持新热点的浏览器中使用iFrame Transport。虽然iFrame Transport简单而聪明,但您并不需要了解它,因为插件将其抽象出来。该插件也是完全免费的。

Basic Plugin将为您完成肮脏的工作,全功能版本甚至还有内置的用户界面。关于如何实现服务器端方法的详细信息很多。基本语法非常简单:

$("#fileUploadForm").fileupload()

如果您正在寻找体重更轻的东西,iFrame Transport Plugin可能就是您所需要的。 (它也是免费的。)我今天刚刚在一个项目中实现了它。这是一个记录良好的JS文件。它增强了$.ajax()功能的标准功能。关键是在AJAX选项列表中指定iframe: true。你的ajax调用可能看起来像这样:

$.ajax("http://localhost", {
    type: $form.attr('method'),
    url: $form.attr('action'),
    data: $form.serialize(),
    dataType: "JSON",
    iframe: true,
    files: $("#MyFileInputId"),
    success: function (data) {
        alert("Success : " + data);
    },
    error: function (data) {
        alert("Error : " + data);
    }
});

另外,如果你想让 extra 确保没有发生非AJAX POST,你可以在你的代码中添加另一行:

$form.submit(function (e) {
    e.preventDefault();
    // do stuff
    return false;
}

preventDefault()将取消POST,即使后面的代码中发生错误。

答案 4 :(得分:0)

var form = $("#fileUploadForm");     
 $.ajax({
      type:form.attr('method'),
      url:form.attr('action'),
      dataType: 'json', //  Expect a return value of json
      data:form.serialize(),
             success: function(data){
      }});