簡體   English   中英

Angular 6 應用程序調用本地主機上的 API 被 CORS 阻止

[英]Angular 6 app call to API on localhost blocked by CORS

Mozilla 開發選項卡網絡選項卡調用 5001 的 GET 方法的詳細信息

我強迫了一個幾個小時后我無法解決的問題,這很常見,但是在網上找到的提示都沒有幫助我。

答案正文

一切都在我的本地 PC 上。 首先,我使用 VS Code 和命令行在 Core 2.1 上開發了一些簡單的 ASP.NET Core WebAPI。 這個 WebAPI 目前有一個簡單的 APIController,它托管在地址上: https://localhost:5001/api/customers/1 (當我將它粘貼到瀏覽器或郵遞員上時,我有一些簡單的 Json 返回,其中包含來自數據庫的一位客戶的數據)。 當然在 Startup.cs 類中我添加了:

app.UseCors(options => 
            options.WithOrigins("http://localhost:4200/")
            .AllowAnyMethod()
            .AllowAnyHeader());

我也有一個過濾器:

    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null)
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");

        base.OnActionExecuted(actionExecutedContext);
    }
}

它被添加到控制器內部和控制器 API 聲明之上的每個方法中。

整個控制器代碼:

namespace BackEnd.Controllers
{
    [AllowCrossSiteJson]
    [Route("api/[controller]")]
    [ApiController]
    public class CustomersController : ControllerBase
    {
        private readonly ICustomersRepository _customersRepository;

        public CustomersController(ICustomersRepository customersRepository)
        {
            _customersRepository = customersRepository;
        }



        // GET api/customers
        [HttpGet]
        public async Task<string> Get()
        {

            var customer = await _customersRepository.GetRandomCustomer();

            return customer.FirstName.ToString();

           // return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [AllowCrossSiteJson]
        [HttpGet("{id}")]
        public async Task<Customer> Get(int id)
        {
            var customer = await _customersRepository.GetCustomerById(id);
            return customer;
        }

        // POST api/values
        [HttpPost]
        public async Task Post([FromBody] Customer customer)
        {
             await  _customersRepository.SaveCustomer(customer);

        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

我正在使用谷歌 Chrome 瀏覽器。

第二 - 我在 Angular 6.1.1 中使用 Node.Js 開發了單獨的項目。 我想做一個快速測試並從 Angular 應用程序調用 Web API。 所以在 AppComponent 內部,我添加了正確的 httpClient 注入,在 OnInit 方法中,我添加了 http.get 請求,如下所示:

this.httpClient.get(`https://localhost:5001/api/customers/${id}`);

我的 Angular 應用程序最初是 Node.js 在我 PC 上的地址http://localhost:4200上的服務器。 (同時 WebAPI 和 Angular 應用程序都在我的 PC 上運行 - 在同一個 Google Chrome 中打開了兩個選項卡)

當我啟動到http://localhost:4200並在控制台中打開 Google Chrome Developer 選項卡時出現錯誤:

CORS 策略阻止了在 ' https://localhost:5001/api/customers/1 ' 從源 ' http://localhost:4200 ' 訪問 XMLHttpRequest:不存在 'Access-Control-Allow-Origin' 標頭在請求的資源上。

我在網上發現這個問題來自瀏覽器(郵遞員通常可以使用來自 WebAPI 的數據)我試圖將內容添加到我的角度文件 proxy.conf.json 中:

{ 
    "/api/*": {
        "target": "https://localhost:5001",
        "secure": false,
        "changeOrigin": true
    }
}

但它根本沒有幫助我。 我不知道在哪里看。

角度代碼:

export class AppComponent {
  title = 'FrontEnd';

  constructor(private apiService: ApiService) { }

  ngOnInit(){
      console.log('hello');
      this.apiService.getCustomerById(1).subscribe((res) => {
         console.log(res);
      });
  }

  public getCustomerById(id :number) {
      return this.httpClient.get(`https://localhost:5001/api/customers/${id}`);
  }
}

問題在於您的服務器,而不是角度問題。 您需要設置您的 web api 以允許跨源資源共享。 您可以通過向 Web api 響應添加其他標頭來實現此目的。

看看如何做到這一點; 閱讀這個答案

在 ASP.Net MVC 中設置 Access-Control-Allow-Origin - 最簡單的方法

Web 瀏覽器會阻止網頁向與提供該網頁的域不同的域發出請求。 這稱為同源策略。 對於每個這樣的請求,瀏覽器都會發出一個 OPTION 調用來查找 Access-Control-Allow-Origin 標頭。 請求域應包含在該標頭中。 您需要通過在 ASP.NET CORE 項目中進行少量更改來啟用此功能。

這篇文章可能有用: https : //stackoverflow.com/a/31942128/4395295

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM