在我的extjs6项目中,我将文件上传到我的webapi。 (使用form ... fileuploadfield)文件成功上传,它应该返回一个简单的字符串列表,但即使文件正确上传,在我的控制器中它总是在form.submit上返回FAILURE。原因......"阻止了一个有起源的框架" http://localhost:57007"从访问跨源框架。"
我相信我读到的地方当我做form.submit时会创建某种导致交叉原点的帧。
通常我不在乎它是否总是返回失败,因为工作仍在完成......但是我想要返回一些如果失败就无法工作的东西。有人能以安全的方式帮助我吗?
PANEL
xtype: 'form',
fileUpload: true, //(1)
width: 500,
frame: true,
title: 'Client Recap Upload Form',
bodyPadding: '10 10 10 10',
margin: '10px 10px 10px 10px',
standardSubmit: false,
defaults: {
anchor: '100%',
allowBlank: false,
msgTarget: 'side',
labelWidth: 50
},
items: [{
xtype: 'fileuploadfield',
emptyText: 'Select a file',
fieldLabel: 'Filename',
name: 'file',
buttonText: 'Choose a file'
}],
buttons: [
{
text: 'Upload',
listeners: {
click: 'onButtonFileUpload'
}
}
]
CONTROLLER
onUploadClientRecap: function (field, e, options, mid) {
var me = this;
if (field.up('form').getForm().isValid()) {
field.up('form').getForm().submit({
url: ExtApplication4.util.GlobalVar.urlTM_UploadClientRecap + mid,
waitMsg: 'Uploading your file...',
success: function (form, o)
{
Ext.Msg.show({
title: 'Result',
msg: o.response.responseText,//.result.result,
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
},
failure: function (form, o)
{
debugger;
Ext.Msg.show({
title: 'Result',
msg: 'File Uploaded...',
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
}
});
}
},
WEB API
[Route("api/tradematch/UploadClientRecap/{mid}")]
[HttpPost]
public List<string> UploadClientRecap(HttpRequestMessage request, int mid)
{
HttpContext context = HttpContext.Current;
HttpPostedFile postedFile = context.Request.Files["file"];
return _repo.UploadClientRecap(postedFile, mid);
}
在我的webapi中我也在我的application_beginrequest
中运行此代码 protected void Application_BeginRequest(object sender, EventArgs e)
{
string[] allowedOrigin = new string[5];
allowedOrigin[0] = "http://localhost:57007";
allowedOrigin[1] = "http://x.com";
allowedOrigin[2] = "https://x.com";
allowedOrigin[3] = "https://www.p.com";
allowedOrigin[4] = "http://www.p.com";
var origin = HttpContext.Current.Request.Headers["Origin"];
if (origin != null && allowedOrigin.Contains(origin))
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, X-Requested-With");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
尝试使用新的webapi返回重定向
[Route("api/tradematch/UploadClientRecap/{mid}")]
[HttpPost]
public HttpResponseMessage UploadClientRecap(HttpRequestMessage request, int mid)
{
HttpContext context = HttpContext.Current;
HttpPostedFile postedFile = context.Request.Files["file"];
var response = Request.CreateResponse(HttpStatusCode.Moved);
response.Headers.Location = new Uri("http://www.google.com/" + "&output=crudeOil");
return response;
//return _repo.UploadClientRecap(postedFile, mid);
}
答案 0 :(得分:0)
文件的上传(POST请求)不受CORS的约束;然而,访问iframe的主体(其上下文目前是跨域起源)当然受制于它,并且是可能发生跨域问题的地方(我已多次看到过这种情况)。
我绕过这种方法的一种方法是采用类似于此jquery插件的方法:https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads#cross-site-iframe-transport-uploads
简而言之,在您的上传处理代码中,您重定向到客户端应用,并传递您希望在查询字符串中上传的结果所需的数据(例如,上传时间,文件名称等)。然后,在您的客户端应用程序中,创建一个简单的重定向页面,该页面将处理传入的查询字符串并对其进行适当处理。
所有这些工作的原因是,一旦重定向发生,iframe的内容最终将与请求在同一个域中提供:
iframe src = cross-domain url
=> POST upload
=> Process upload
=> Redirect response to same domain as original client app
iframe src = original requesting client
因此,您可以通过JS成功阅读内容,而无需依赖iframe的跨域政策。
以下是您上传代码(在Node中)创建重定向的基本示例:
app.post('/api/photo', function(req, res) {
if (done == true) {
var params = {
sometext: "I am some text",
success: true,
msg: 'The upload was successful',
filename: 'Avatar.png'
};
res.redirect('http://myapp.com/results.html?data=' + JSON.stringify(params));
}
});
然后,您的重定向文件来处理响应:
<html>
<head>
<meta charset="utf-8">
<title>Cross-Domain Upload Redirect Page</title>
</head>
<body>
<script>
// strip off "?data="...
var data = window.location.search.slice(6),
decodedJSON = decodeURIComponent(data);
// set JSON string into innerText and textContent
// so Ext.data.Connection can treat it
// the same as regular iframe uploads
document.body.innerText=document.body.textContent=decodedJSON;
</script>
</body>