【问题标题】:How to enable CORS on C# server?如何在 C# 服务器上启用 CORS?
【发布时间】:2022-01-20 00:57:57
【问题描述】:

我正在开发一个 Web 应用程序,它有一个云服务器 (nodeJS) 和一个本地服务器 (C#) 来连接 PC 的串行端口。来自云服务器的网页向本地服务器发起请求,报错

Access to fetch at 'http://localhost:3100/connection' from origin 'http://cloud.tissuelabs.com' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `local`

我尝试在请求中添加标头

'headers': {'Access-Control-Allow-Origin': '*'}

但这并不能解决我的问题。我使用 CORS 库在 python 中解决了这个问题,但我仍然想在 C# 中解决这个问题(因为性能)。这是我用 C# 编写的服务器

private void InitializeServer()
    {
        myServer = new Thread(Server);
        myServer.Start(this);
    }

    private void Server(Object _obj)
    {
        Route.Add((req, props) => req.Url.LocalPath.ToLower().EndsWith("connection"),
            (req, res, args) =>
        {
            if (req.HttpMethod == "GET")
            {
                Regex rx = new Regex(@"port=(?<word>\w+)",
                    RegexOptions.Compiled | RegexOptions.IgnoreCase);
                MatchCollection matches = rx.Matches(req.Url.Query);
                if (matches.Count > 0)
                {
                    bool on = true;
                    bool printing = true;
                    WriteLog($"GET {req.Url.LocalPath + req.Url.Query}");
                    WriteLog($"{matches[0].Groups["word"].Value}");
                    string output = "{" + $"'on':{on}, 'printing':{printing}, 'queue': {10}" + "}";
                    res.AsText(output);
                }
                else
                {
                    WriteLog($"GET {req.Url.LocalPath}");
                    string[] ports = SerialPort.GetPortNames();
                    string output = "{'ports':[";
                    foreach (string port in ports)
                    {
                        output += "{" + $"'port':'{port}', 'name':'{port}'" + "}";
                    }
                    output += "]}";
                    res.AsText(output);
                }
            } 
            else if (req.HttpMethod == "POST")
            {
                WriteLog("POST /connection");

                Stream stream = req.InputStream;
                StreamReader sr = new StreamReader(stream);
                JsonSerializer serializer = new JsonSerializer();
                Connection con = (Connection)serializer.Deserialize(sr, typeof(Connection));
                connectSerial(con.port);

                res.AsText("{'ok': True}");
            } 
            else if (req.HttpMethod == "DELETE")
            {
                WriteLog("DELETE /connection");
                res.AsText("OK");
            }
        });

        
        

        HttpServer.ListenAsync(3100, System.Threading.CancellationToken.None, Route.OnHttpRequestAsync)
        .Wait();
    }

当我将访问控制允许来源添加到标题时,它适用于 Firefox,但不适用于 Chrome

res.AddHeader("Access-Control-Allow-Origin", "*");

有没有我可以与 SimpleHttp 一起使用的库?我也在使用 CefSharp 来呈现网页。有什么方法可以配置 chromium 网络浏览器以忽略 CORS 错误?

【问题讨论】:

  • 有什么理由不能添加另一个 else if 子句else if (req.HttpMethod == "OPTIONS")?如果是OPTIONS,那么在response中添加Access-Control-Allow-Origin header?
  • 没有“C# 服务器”之类的东西。听起来 MAYBE 您可能正在使用Microsoft Web API?您配置 CORS 的确切 HOW 部分取决于您的库(例如 ASP.Net MVC 与 Web API)和 .Net 版本(例如 .Net 4.x 与 ASP.Net Core 与 .Net 6) .这可能会有所帮助:Enable cross-origin requests in ASP.NET Web API 2
  • 你可以看看这个答案,看看它是否适用于你的情况:stackoverflow.com/a/70665455/1807452
  • 错误消息清楚地提到了 CSP 违规。 CSP!= CORS。发出请求的页面的 CSP 是什么?设置在哪里?
  • @peinearydevelopment 我尝试在响应中添加标头。但即使我 GET 请求,我仍然会收到 CORS 错误。如果 req.httpmethod == "OPTIONS" 没有成功,我也尝试添加 else

标签: c# cors asp.net-web-api2


【解决方案1】:

CORS问题应该在服务器端解决,必须有一个关键字或者你应该设置“项目配置文件”的东西

我找到了

namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

只是快速谷歌搜索,请查看更多信息:https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api

第一种方法为所有控制器启用缓存,而第二种方法是基于控制器的,在这种情况下允许仅来自给定来源的核心请求,如果您想允许所有来源,则应设置“*”作为价值。

【讨论】:

    猜你喜欢
    • 2020-08-27
    • 2017-11-24
    • 1970-01-01
    • 2019-12-24
    • 2017-02-20
    • 2018-01-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    相关资源
    最近更新 更多