本来,通过jquery from,ajax上传文件挺容易的,但是,上传完之后想返回json的话,颇费了一些周折。
asp.net mvc 中可以直接返回一个JsonResult,例如
代码
public
JsonResult UploadImage()
{
{
//上传文件的处理
return new JsonResult
{
Data = _imageService.NewUrl,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
return new JsonResult
{
Data = _imageService.NewUrl,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
然后
代码
$().ready(function () {
var options = {
dataType: ' json ' ,
beforeSubmit: showRequest,
error:showError,
success: showResponse
};
$( ' #myform ' ).ajaxForm(options);
});
function showRequest(formData, jqForm, options) {
alert( ' 发送前 ' );
return true ;
}
function showError(data) {
alert('error');
}
function showResponse(data, status) {
alert( ' 发送后 ' );
}
var options = {
dataType: ' json ' ,
beforeSubmit: showRequest,
error:showError,
success: showResponse
};
$( ' #myform ' ).ajaxForm(options);
});
function showRequest(formData, jqForm, options) {
alert( ' 发送前 ' );
return true ;
}
function showError(data) {
alert('error');
}
function showResponse(data, status) {
alert( ' 发送后 ' );
}
做完这些,应该就能读取Json,没想到跳出一个文件保存窗口,保存下来的内容,就是我们发送的Json。
百度了一番,发现不仅asp.net平台有问题,J2EE平台也有这么个问题,解决的办法,是直接返回HTML。
public ActrionResult UploadImage()
{
return
Content(
"
{error: 'file size is zero'}
"
,
"
text/html
"
);
}
这样做之后,终于alert了,但是弹出的信息是error。
仔细研究了一下jquery form官方的例子,发现json内容应该被<textarea>包围
修改后如下:
public
ActrionResult UploadImage()
{
return Content( " <textarea>{error: 'file size is zero'}</textarea> " , " text/html " );
}
{
return Content( " <textarea>{error: 'file size is zero'}</textarea> " , " text/html " );
}
修改完成后,依然跳到showError,通过搜索引擎再没搜索到有用的信息,不得不调试jquery.form.js
搜索textarea,很容易找到了合适的断点
代码
try
{
if (opts.dataType == ' json ' || opts.dataType == ' script ' ) {
// see if user embedded response in textarea
var ta = doc.getElementsByTagName( ' textarea ' )[ 0 ];
if (ta)
xhr.responseText = ta.value;
else {
// account for browsers injecting pre around json response
var pre = doc.getElementsByTagName( ' pre ' )[ 0 ];
if (pre)
xhr.responseText = pre.innerHTML;
}
}
else if (opts.dataType == ' xml ' && ! xhr.responseXML && xhr.responseText != null ) {
xhr.responseXML = toXml(xhr.responseText);
}
data = $.httpData(xhr, opts.dataType); // 这里报错
}
catch (e){
log( ' error caught: ' ,e);
ok = false ;
xhr.error = e;
$.handleError(opts, xhr, ' error ' , e);
}
if (opts.dataType == ' json ' || opts.dataType == ' script ' ) {
// see if user embedded response in textarea
var ta = doc.getElementsByTagName( ' textarea ' )[ 0 ];
if (ta)
xhr.responseText = ta.value;
else {
// account for browsers injecting pre around json response
var pre = doc.getElementsByTagName( ' pre ' )[ 0 ];
if (pre)
xhr.responseText = pre.innerHTML;
}
}
else if (opts.dataType == ' xml ' && ! xhr.responseXML && xhr.responseText != null ) {
xhr.responseXML = toXml(xhr.responseText);
}
data = $.httpData(xhr, opts.dataType); // 这里报错
}
catch (e){
log( ' error caught: ' ,e);
ok = false ;
xhr.error = e;
$.handleError(opts, xhr, ' error ' , e);
}
catch到的信息是“Invalid JSON”。原来从jquery1.4开始,键和值都必须使用两个引号包围,改为以下内容之后解决
return
Content(
"
<textarea>{'error': 'file size is zero'}</textarea>
"
,
"
text/html
"
);
在这个问题上,耗费了一整天的时间,记录下来整个过程,希望其他人能用上