extjs form.submit由于"访问跨源框架而失败"

时间:2017-08-04 17:46:42

标签: extjs cross-domain form-submit

在我的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);
    }

1 个答案:

答案 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>