由于“访问跨域框架",extjs form.submit失败. [英] extjs form.submit failed due to "accessing a cross-origin frame"
问题描述
在extjs6项目中,我正在将文件上传到我的webapi. (使用form ... fileuploadfield)文件已成功上传,并且应该返回一个简单的字符串列表,但是即使文件已正确上传,在我的控制器中它也总是在form.submit上返回FAILURE.原因..."从访问跨域框架阻止了源为" http://localhost:57007 的框架" ."
In my extjs6 project I am uploading a file to my webapi. (using form... fileuploadfield) The file gets successfully uploaded and it is supposed to return a simple string list however even though the file gets uploaded properly, in my controller it ALWAYS returns FAILURE on form.submit. Reason..."Blocked a frame with origin "http://localhost:57007" from accessing a cross-origin frame."
我相信我在某处读到,当我进行form.submit提交时,它会创建某种导致交叉原点的框架.
I believe I read somewhere that when I do form.submit it creates some kind of frame that causes the cross origin.
通常我不关心它是否总是返回失败,因为作业仍在完成...但是我想返回一些如果失败则无法正常工作的东西.有人可以通过一种安全的方式帮助我吗?
Normally I wouldn't care if it always returns failed because the job is still getting done... but I want to return something which wont work if it fails. Can someone help me with a SECURE way of doing this?
面板
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'
}
}
]
控制器
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中运行此代码
in my webapi I am also running this code in my 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返回重定向
trying new webapi to return redirect
[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);
}
推荐答案
文件的上传(POST请求)不受CORS的限制;但是,访问iframe的主体(其上下文当前是跨域起源)肯定是受其约束的,并且可能是发生跨域问题的地方(我已经看过很多次了).
The upload (POST request) of the file is not subject to CORS; however, accessing the body of the iframe (whose context is currently a cross-domain origin) IS certainly subject to it, and is where the cross-domain issue is probably occurring (I've seen this many times).
我规避此问题的一种方法是采用类似于此jquery插件的方法:
One way I've circumvented this is to employ an approach similar to what this jquery plugin does: https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads#cross-site-iframe-transport-uploads
简而言之,在您的上传处理代码中,您重定向到客户端应用程序,并在查询字符串中传递希望通过上传获得的所需数据(例如,上传时间,文件名称等).然后,在您的客户端应用程序中,创建一个简单的重定向页面,该页面将处理传入的查询字符串并进行适当处理.
In short, in your upload-handling code, you redirect to your client-side app, and pass along the desired data that you wish to be available as a result of the upload in the querystring (e.g., upload time, file name, etc). Then, in your client-side app, create a simple redirect page that will handle the incoming querystring and process it appropriately.
所有这些工作的原因是,一旦发生重定向,iframe的内容最终将与请求来自同一域:
The reason all of this works is that content of the iframe will be ultimately served from the same domain as the request, once the redirect has occurred:
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的跨域策略.
Because of this, you can successfully read the content via JS without stepping on the cross-domain policies of iframes.
这是一个非常基本的示例,说明您的上传代码(在Node中)如何创建重定向:
Here's a very basic example of what your upload code (in Node) might look like to create the redirect:
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));
}
});
然后,您的重定向文件来处理响应:
And then, your redirect file to handle the response:
<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>
这篇关于由于“访问跨域框架",extjs form.submit失败.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!