Aurelia 浏览器控制台错误 - POST 请求 - 对预检请求的响应未通过访问控制检查

Aurelia Browser Console Error - POST Request - Response to preflight request doesn't pass access control check

美好的一天 Whosebug!我提出了一个新问题,因为我是 Web 服务的初学者,目前与我的问题类似的主题对我来说没有任何意义。我非常欢迎学习新东西。我很高兴收到社区的回应和支持。

目前我正在一家公司接受 Web 开发培训,我们的任务之一是使用 "Microsoft ASP.NET Core 2.0 Web API" 使用 MVC 创建 Web 服务并为我们的 Aurelia 应用程序启用 CORS。

我的 Aurelia 应用托管在 http://localhost:9000/ and the webservice is in http://localhost:5000/ 作为测试。

Here are the problems that I've encountered and my observations:

  1. Whenever I run my Aurelia app, I am getting this error on the browser console: "Failed to load http://localhost:5000/api/sample: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access." Is there any configuration on my C# code that i need to add in order for this error to go away?

  2. I used PostMan in order to check if the web service is working, and yes it did work. So I was wondering what was wrong if I access the web service from my Aurelia application, it generates an error. I guess the error is in the client side? Here is the screenshot of the PostMan request and response.

  1. If I pass an object from my aurelia app to the web service as HTTP POST request, does the web service understands/maps right away the object values received?

    1. And also on the Web API Debug Console, it says: "Request method POST not allowed in CORS policy."

为了简单起见,我在我的 Aurelia app.ts 上使用 TypeScript 编写了这段代码,它通过 HTTP Post 动词请求示例数据:

import { inject } from 'aurelia-framework';
import { HttpClient } from 'aurelia-http-client';

@inject(HttpClient)
export class WebAPITest {

  private httpClient: HttpClient;
  private static readonly BASE_URL = `http://localhost:5000/api/`;
  private message = `Web API Access Test! Pls. check the console.`;

  constructor(httpClient: HttpClient) {
    this.httpClient = httpClient;
    this.httpClient.configure(requestBuilder => {
      requestBuilder.withBaseUrl(WebAPITest.BASE_URL);
      requestBuilder.withHeader('Content-Type', 'application/json'); // (?) Need clarifications.
    });
  }

  activate() {
    let sampleData = new SampleData();
    return this.httpClient.post(`sample`, sampleData)
      .then(response => {
        if (response.isSuccess) {
          this.data = response.content;
          console.log(`SampleData Web Service Call SUCCEED!`);
        } else {
          console.log(`SampleData Web Service Call FAILED!`);
        }
    });
  }
}

export class SampleData {
   public name: string;
   public age: number;

   constructor() {
    this.name = "Garfield";
    this.age = 5;
   }
}

这是我的 ASP.NET Core 2.0 MVC Web API 的代码:(Startup.cs)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Syslog.Web.GradeSheet.Backend
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddCors();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // For now it only accepts requests from localhost port 9000 which is the seat of our Aurelia applications.
            app.UseCors(corsPolicyBuilder => {
                corsPolicyBuilder.WithOrigins("http://localhost:9000");
            });

            app.UseMvc();

            // Normally this will be fired up when no route has been matched.
            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Welcome To GradeSheet Web Service! MVC has not found any Route that has been matched yet.");
            });
        }
    }
}

这是我的 ASP.NET Core 2.0 MVC Web API 的代码:(SampleController.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace Syslog.Web.GradeSheet.Backend.Controllers
{
    [Route("api/[controller]")]
    public class SampleController : ControllerBase
    {
        [HttpPost]
        public IActionResult getSampleObject([FromBody] SampleData sampleData) {

            if(ModelState.IsValid) {
                System.Diagnostics.Debug.WriteLine($"PRINTED: {sampleData.name} is {sampleData.age} years old.");
            } else {
                System.Diagnostics.Debug.WriteLine("ModelState is not Valid.");
            }


            return Ok($"Ok, got it, {sampleData.name}! You are {sampleData.age} years old.");
        }
    }

    public class SampleData {
        public string name { get; set; }
        public int age { get; set; }
    }
}

Thank you very much for the time reading my problem. I would appreciate any solutions, recommendations, additional information or criticisms on my code. Have a nice day.

问题出在此处的 MVC Startup 中。您没有完全配置您的 CORS 构建器,您只配置了允许的来源,而不是配置的其余部分。

如果你把它改成这样,它应该可以正常工作:

app.UseCors(corsPolicyBuilder => {
  corsPolicyBuilder.WithOrigins("http://localhost:9000").AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});