请帮帮我们,这个是一个主要的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.
答案 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()
不需要任何参数(如果需要,可以传入选项)。因为我没有传入参数,所以附加了回调,在本例中是done
和fail
(而不是success
和error
)。
答案 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){
}});