由于“访问跨域框架",extjs form.submit 失败; [英] extjs form.submit failed due to "accessing a cross-origin frame"
问题描述
在我的 extjs6 项目中,我将一个文件上传到我的 webapi.(使用表单... 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
});
}
});
}
},
网络接口
[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 插件的方法:https://github.com/blueimp/jQuery-File-Upload/wiki/Cross-domain-uploads#cross-site-iframe-transport- 上传
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成功读取内容,而无需踏入iframes的跨域策略.
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屋!