处理CORS preflight请求ASP.NET MVC行动 [英] Handling CORS Preflight requests to ASP.NET MVC actions

查看:150
本文介绍了处理CORS preflight请求ASP.NET MVC行动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图执行一个跨域POST请求到ASP.NET MVC控制器动作。该控制器操作接受和放大器;使用的各种参数。的问题是,preflight请求发生时,控制器采取行动实际上试图执行与放大器;因为OPTIONS请求没有通过任何数据,控制器动作抛出一个500 HTTP错误。如果我删除code使用参数,或参数本身,整个请求链成功完成。

I'm trying to perform a cross-domain POST request to an ASP.NET MVC controller action. This controller action accepts & uses various parameters. The problem is that when the preflight request happens, the controller action actually attempts to execute & because the OPTIONS request doesn't pass any data, the controller action throws out a 500 HTTP error. If I remove the code that uses the parameter, or the parameter itself, the entire request chain is completed successfully.

这是如何实现的一个例子:

An example of how this is implemented:

控制器动作

public ActionResult GetData(string data)
{
    return new JsonResult
    {
        Data = data.ToUpper(),
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
}

客户端code

<script type="text/javascript">
        $(function () {
            $("#button-request").click(function () {
                var ajaxConfig = {
                    dataType: "json",
                    url: "http://localhost:8100/host/getdata",
                    contentType: 'application/json',
                    data: JSON.stringify({ data: "A string of data" }),
                    type: "POST",
                    success: function (result) {
                        alert(result);
                    },
                    error: function (jqXHR, textStatus, errorThrown) {
                        alert('Error: Status: ' + textStatus + ', Message: ' + errorThrown);
                    }
                };

                $.ajax(ajaxConfig);
            });
        });
    </script>

现在,只要preflight请求发生,它会返回一个HTTP 500 code,因为数据参数为空,看到OPTIONS请求不传递任何值。

Now, whenever the preflight request happens, it returns a 500 HTTP code, because the "data" parameter is null, seeing as the OPTIONS request doesn't pass any values.

服务器应用程序已经设置在我的本地IIS在端口8100和放大器;运行客户端code中的页面设置端口8200来模拟跨域调用。

The server application has been set up in my local IIS on port 8100 & the page running the client-side code is set up on port 8200 to mimic the cross-domain calls.

我也用下面的头配置的机子上(8100):

I have also configured the host (on 8100) with the following headers:

Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Origin: http://localhost:8200

一个解决办法我已经找到了,是要检查执行的动作和放HTTP方法;如果它是一个OPTIONS请求,只是返回空白的内容,否则执行的操作code。像这样:

One workaround I had found, was to check the HTTP method that executes the action & if it's a OPTIONS request to just return blank content, otherwise execute the action code. Like so:

public ActionResult GetData(string data)
{
    if (Request.HttpMethod == "OPTIONS") {
        return new ContentResult();
    } else {
        return new JsonResult
        {
            Data = data.ToUpper(),
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
}

但这种方法感觉很笨重给我。我认为将这种逻辑到属性,但即使这意味着每一个装饰,将让使用CORS它称为动作。

But this approach feels very clunky to me. I considered adding this sort of logic to an Attribute, but even this would mean decorating every action that will get called using CORS with it.

有没有更优雅的解决方案,以获得此功能工作?

Is there a more elegant solution to getting this functionality to work?

推荐答案

所以,我发现,有效的解决方案。对于每个请求,我检查它是否是一个CORS请求&安培;请求是否即将与OPTIONS动词,这表明它是preflight请求。如果是,我只是发送一个空的响应回(只包含当然IIS中配置的头),从而否定控制器动作执行。

So I have found a solution that works. For each request, I check whether it's a CORS request & whether the request is coming in with the OPTIONS verb, indicating that it's the preflight request. If it is, I just send an empty response back (which only contains the headers configured in IIS of course), thus negating the controller action execution.

然后,如果客户确认它允许执行基于从preflight返回标头的要求,实际的POST进行&放大器;控制器的执行动作。和示例我code的:

Then if the client confirms it's allowed to perform the request based on the returned headers from preflight, the actual POST is performed & the controller action is executed. And example of my code:

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") {
        Response.Flush();
    }
}

如前所述,这为我工作,但如果有谁知道一个更好的方式,或在我目前的执行任何瑕疵的,我会AP preciate听到他们。

As mentioned, this worked for me, but if anyone knows of a better way, or of any flaws in my current implementation, I would appreciate to hear about them.

这篇关于处理CORS preflight请求ASP.NET MVC行动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆