【问题标题】:Why do I keep getting CORS errors even though I've configured it correctly即使我已正确配置,为什么我仍会收到 CORS 错误
【发布时间】:2021-07-17 14:19:44
【问题描述】:

所以我使用 Vue 开发了一个客户端,而后端我使用的是 ASP.NET Core Web API。 我在客户端上有一个表单,当我单击按钮将表单提交到服务器时发生错误。

如果我打开 Visual Studio 并在“https://localhost:44393”上运行项目并在“http://localhost:8080/”上为客户端提供服务 一切正常,我发布表单完全没有问题。

但是.. 如果我随后将 Web API 发布到我在 smarterasp.net 上托管它的位置并更改从

fetch("https://localhost:44393/Account/AddServer", {
        ..

fetch("https://api.mywebsite.com/Account/AddServer", {
        ..

它会在 Google Chrome 控制台中引发此错误

Access to fetch at 'https://api.mywebsite.com/Account/AddServer' 
from origin 'http://localhost:8080' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

好的,现在您可能认为我不应该尝试从“http://localhost:8080”访问它。好的,我将文件上传到我的网络服务器,在 namescheap 然后它抛出这个错误

Access to fetch at 'https://api.mywebsite.com/Account/AddServer' 
from origin 'https://mywebsite.com' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

这是执行此操作的唯一端点,在其他端点上发布或获取不会引发任何错误。

问题
为什么只有在发布后调用 API 时才会抛出错误,而不是在 API 本地运行时抛出错误?表单之间的唯一区别是我正在使用的这个引发异常的表单使用enctype="multipart/form-data"

这是它正在调用的操作

[EnableCors("AllowEverything")]
[Authorize]
[HttpPost]
public IActionResult AddServer(ServerModel server)
{
    var username = User.Identity.Name;

    /* Validate data */
    if (ModelState.IsValid)
    {
        var httpRequest = HttpContext.Request;
        //var files = httpRequest.Form.Files;
        //return Ok();
        ///*If the user added a banner*/
        if (httpRequest.Form.Files.Count() > 0)
        {
            using (var ms = new MemoryStream())
            {
                httpRequest.Form.Files[0].CopyTo(ms);
                var fileBytes = ms.ToArray();
                ImageExtParser iep = new ImageExtParser(fileBytes);
                var type = iep.CheckFileType();
                if (type == null)
                {
                    return BadRequest(Json("Invalid banner image."));
                }

                var bannerName = Guid.NewGuid() + "." + type;
                server.Banner = "banners/" + bannerName;

                FtpWebRequest request = (FtpWebRequest)WebRequest.Create($"ftp://myftpserver.com" + bannerName);
                request.Method = WebRequestMethods.Ftp.UploadFile;
                request.Credentials = new NetworkCredential("myUsername", "hidingthecredentialsobviously");

                using (Stream requestStream = request.GetRequestStream())
                {
                    requestStream.Write(fileBytes, 0, fileBytes.Length);
                }

                using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
                {
                    var k = response.StatusCode;
                }
            }
        }


        if (_dbContext.Servers.Where(x => x.IPHost == server.IPHost).FirstOrDefault() == null)
        {
            server.Owner = username;

            /* */
            if (_dbContext.Servers.Where(x => x.IPHost == server.IPHost).FirstOrDefault() != null)
            {
                return BadRequest(Json($"Server with IPHost {server.IPHost} has already been added."));
            }

            server.Tags = "test";
            _dbContext.Servers.Add(server);
            _dbContext.SaveChanges();
            return Ok();
        }
        else
        {
            ModelState.AddModelError("IPHost", " already exists.");
            return BadRequest(Json(ModelState));
        }
    }
    else
    {
        return BadRequest(Json(ModelState));
    }
}

ConfigureServices(我允许一切用于测试目的)

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(name: "AllowEverything",
                      builder =>
                      {
                          builder.AllowAnyOrigin()
                                 .AllowAnyMethod()
                                 .AllowAnyHeader();
                      });
    });

配置

app.UseHttpsRedirection();
app.UseRouting();

app.UseCors("AllowEverything");

app.UseAuthentication();
app.UseAuthorization();

JavaScript

postData(e) {
  let formData = new FormData();
  formData.append("Name", name);
  formData.append("IPHost", iphost);
  formData.append("Country", country);
  formData.append("Description", descripton);
  formData.append("Banner", document.getElementById("bannerup").files[0]);

  fetch("https://api.mywebsite.com/Account/AddServer", {
    method: "post",
    body: formData,
    headers: new Headers({
      Authorization: "Bearer " + this.getCookie("Bearer"),
    }),
  })
    .then((res) => {
      if (res.ok) {
        document.location = "/Profile";
      }
      return res;
    })
    .then((res) => res.json())
    .then((vals) => {
      console.log(vals);
      for (var key in vals) {
        this.addError(key, vals[key]);
      }
    });

  e.preventDefault();
}

【问题讨论】:

  • 尝试从动作中移除 [EnableCors("AllowEverything")]
  • 不幸的是,这并没有改变什么
  • 您的 ASP.NET Core API 在发布时很可能会引发异常。这通常意味着没有设置 CORS 标头,因此请检查您的服务器日志以查看是否有任何异常迹象。
  • @KirkLarkin 听起来可能是这样,我记得昨天我在本地遇到异常时收到此错误,我会检查一下

标签: vue.js asp.net-core .net-core fetch asp.net-core-webapi


【解决方案1】:

问题不在后端,它的 chrome 不允许在 localhost 上获取 https

添加

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

在获取标头中

【讨论】:

  • 是的,和那个很像,但是 Headers 只是一个对象而不是一个类的例子,这里的例子代码hatebin.com/wbvnjolbkc
猜你喜欢
  • 2022-08-20
  • 2022-06-10
  • 2021-07-16
  • 1970-01-01
  • 2016-07-21
  • 2020-03-07
  • 2022-11-03
  • 2022-01-18
  • 2020-01-29
相关资源
最近更新 更多