【问题标题】:Angular 6 Asp.Net (not Core) Web Api CORS request failsAngular 6 Asp.Net(非核心)Web Api CORS 请求失败
【发布时间】:2019-02-04 01:21:27
【问题描述】:

我正在构建一个 .Net Web Api,它将被 Angular 6 客户端使用,但由于某种原因,我无法使其在我的开发环境中工作。

我从一个非常简单的 Web Api 开始,它只返回一个字符串(用于前端和后端测试目的之间的通信):

// GET: api/Login
public IEnumerable<string> Get()
{
    return new string[] { "Now it works!" };
}

// POST: api/Login
public void Post([FromBody]string value)
{
    string strTest = "I'm doing just nothing";
}

然后在我的 Angular 6 应用程序中,我有一个带有以下发布请求的方法:

return this.http.post<any>(`http://localhost:9810/api/Login`, { username, password })
            .pipe(map(user => {
                // login successful if there's a jwt token in the response
                if (user && user.token) {
                    // store user details and jwt token in local storage to keep user logged in between page refreshes
                    localStorage.setItem('currentUser', JSON.stringify(user));
                }

                return user;
            }));

在我的第一次尝试中,我的所有响应都以响应失败:

zone.js:2969 OPTIONS http://localhost:9810/api/Login 405(不允许的方法)
登录:1 无法加载 http://localhost:9810/api/Login:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'http://localhost:4200'。

所以在调查之后,我已经在我的 WebApi .Net 项目中添加了 CORS 支持:

1) 已安装的 Nuget 包:

Microsoft.AspNet.WebApi.Cors
Microsoft.AspNet.Cors

2) 在 WebApiConfig 中注册方法:

var cors = new EnableCorsAttribute("http://localhost:4200", "*", "*");
// or var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

3) 替代 2) 在 Api 控制器类头中:

[EnableCors(origins: "http://localhost:4200", headers: "*", methods: "*")]

但似乎没有任何工作,请求总是失败,并出现与浏览器控制台中上述相同的错误。

我尝试在 http://localhost:9000 上创建一个自托管 WebApi 监听 http 调用,以及我最后一次尝试在我的本地 Windows 10 IIS 服务器中使用 9810 端口发布 WebApi。

如果我像这样“http://localhost/api/Login”在浏览器中访问 url,那么字符串会像这样返回:

<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
    <string>Now it works!</string>
</ArrayOfstring>

控制台中没有显示任何错误,但只要我尝试通过 Angular(默认端口 4200)发出请求,请求就会失败并出现 CORS 错误。

我被困住了。如果我不能让它在 Angular 中工作,我将无法进行调试和测试。

谢谢。

编辑 1:添加了 Chrome 网络标签信息。

一般:

请求网址:http://localhost:9000/api/Login
请求方法:OPTIONS
状态码:405 方法不允许
远程地址:[::1]:9000
推荐人政策:降级时无推荐人

响应标头:

允许:GET、POST
内容长度:76
内容类型:应用程序/json;字符集=utf-8
日期:格林威治标准时间 2018 年 8 月 29 日星期三 10:32:36
服务器:Microsoft-HTTPAPI/2.0

请求标头:

接受:/
接受编码:gzip、deflate、br
接受语言:es-ES,es;q=0.9
访问控制请求标头:内容类型
访问控制请求方法:POST
连接:保持活动
主机:本地主机:9000
来源:http://localhost:4200
用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

【问题讨论】:

  • 当您收到请求时(查看浏览器的网络工具),它是否包含 Access-Control-Allow-Methods 标头?该标头的值是否包含选项?如果您使用 IIS,您可能还需要允许该方法通过 IIS,并删除任何其他可能正在捕获 OPTIONS 请求的处理程序。
  • zone.js:2969 OPTIONS http://localhost:9810/api/Login 405 (Method Not Allowed) 应该将您指向正确的位置。它告诉您对您的服务器的 OPTIONS 请求在某处被拒绝。通常这是 IIS 拦截它并将请求抛出。在&lt;handlers&gt; 下,您可以添加&lt;remove name="OPTIONSVerbHandler" /&gt;,这可能会使其工作:)
  • 您好@Mardoxx,感谢您的回复。您的意思是在 WebApi web.config 中添加此标签吗?因为在我的 Web.config 中,我已经有一个 标记。
  • 感谢您的帮助@ADyson。我已编辑问题并添加了您要求的信息。
  • "Allow: GET,POST" 就是问题所在。您还需要使其允许 OPTIONS。

标签: c# angular asp.net-web-api


【解决方案1】:

在整个上午都在挣扎并尝试了你们每个人在这里提出的所有建议之后,我无法相信我的问题最终会这么容易解决。

关于@Madpop 建议 Application_BeginRequest(出于任何原因)从未被解雇(不想花太多时间调查原因)。

@Steveland 解决方案涉及添加依赖注入,除了我没有使用 Asp.Net Core 而是 Asp.Net framework 4.6 之外,这对我来说有点复杂(我没有太多经验)。

我正在寻找一个简单的解决方案来解决我认为应该很容易解决的问题,并且关键是附加

[HttpPost]
[HttpOptions] //this was the key
[Authorize]

到 Post 方法头。这是我在请求中允许“选项”动词的唯一方法。

我不知道这是否是实现这一目标的最佳方式,但现在它有效(让我知道你们的想法)。

感谢大家在这里提供的每一个帮助,并表示感谢,由于我不是这个主题(Angular + Web Api)的专家,我想最后问下一个:

当 api 将被部署到服务器时,我是否必须将这个 [HttpOptions] 也用于生产,或者现在只需要它来进行本地调试和测试?

编辑 1:

经过测试,我注意到它适用于自托管 Web Api,但是当我将 Web Api 发布到本地 IIS 时,我在浏览器中收到“415 Unsupported Media Type”:(

【讨论】:

  • 遗憾的是,即使支持正确的媒体类型,它也无法工作,因为我遇到了同样的问题,它会通过错误 500 内部服务器错误。服务器甚至没有收到发布请求,试图解决 cors 问题,但它没有任何不同。你找到解决办法了吗?
【解决方案2】:

关于 cors 问题,我也遇到了类似的问题,我创建了一个 global.asax 文件,并在其中放置了以下代码

protected void Application_BeginRequest()
{

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        //These headers are handling the "pre-flight" OPTIONS call sent by the browser
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://staging.example.com:8044");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Accepts, Content-Type, Origin, X-My-Header");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "60");
        HttpContext.Current.Response.End();
    }

}

它在 angular 6 和 ionic 3 中也适用于我,并且在所有这些尝试安装之前 https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en

上面的chrome插件并激活它然后尝试运行应用程序

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-25
    • 2021-06-25
    • 2021-12-08
    • 2023-03-18
    • 2023-03-06
    • 2019-02-05
    • 2019-08-23
    • 2021-03-11
    相关资源
    最近更新 更多