Api web MVC: Không có tiêu đề 'Access-Control-allow-Origin' trên tài nguyên được yêu cầu


127

Tôi đã thử tất cả mọi thứ được viết trong bài viết này: http://www.asp.net/web-api/overview/security/eneac-cross-origin-requests-in-web-api , nhưng không có gì hoạt động. Tôi đang cố gắng lấy dữ liệu từ webAPI2 (MVC5) để sử dụng trong một tên miền khác bằng angularJS.

bộ điều khiển của tôi trông như thế này:

namespace tapuzWebAPI.Controllers
{
    [EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
    [RoutePrefix("api/homepage")]
    public class HomePageController : ApiController
    {
        [HttpGet]
        [Route("GetMainItems")]
        //[ResponseType(typeof(Product))]
        public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
        {


            HomePageDALcs dal = new HomePageDALcs();
            //Three product added to display the data

            //HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));


            List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
            return items;

        }      
    }
}

1
Đồng thời chia sẻ mã góc của bạn để yêu cầu
cors

2
Có lẽ không có vấn đề gì với mã góc cạnh của anh ta vì hầu hết các CORS gặp phải chỉ vì cấu hình máy chủ
sam

Tôi có cùng kiểu thiết lập, tôi nhận thấy rằng khi tôi yêu cầu một hành động không tồn tại trên API và WebApi đang trả về 404, tiêu đề CORS bị thiếu và trình duyệt sẽ phàn nàn. Vì vậy, có lẽ nó đơn giản như vậy.
Robin van der Knaap

Câu trả lời:


294

Bạn cần kích hoạt CORS trong Api Web của bạn . Cách dễ dàng và ưa thích hơn để kích hoạt CORS trên toàn cầu là thêm phần sau vào web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Xin lưu ý rằng tất cả các Phương thức đều được chỉ định riêng, thay vì sử dụng *. Điều này là do có một lỗi xảy ra khi sử dụng *.

Bạn cũng có thể kích hoạt CORS theo mã.

Cập nhật Gói NuGet
sau là bắt buộc : .Microsoft.AspNet.WebApi.Cors

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();

        // ...
    }
}

Sau đó, bạn có thể sử dụng [EnableCors]thuộc tính trên Hành động hoặc Bộ điều khiển như thế này

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]

Hoặc bạn có thể đăng ký nó trên toàn cầu

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("http://www.example.com", "*", "*");
        config.EnableCors(cors);

        // ...
    }
}

Bạn cũng cần xử lý các Options yêu cầu preflight với HTTP OPTIONScác yêu cầu.

Web APIcần đáp ứng Optionsyêu cầu để xác nhận rằng nó thực sự được cấu hình để hỗ trợ CORS.

Để xử lý việc này, tất cả những gì bạn cần làm là gửi lại phản hồi trống . Bạn có thể làm điều này trong hành động của mình hoặc bạn có thể thực hiện nó trên toàn cầu như thế này:

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

Kiểm tra thêm này đã được thêm vào để đảm bảo rằng cũ APIsđược thiết kế để chỉ chấp nhận GETPOSTcác yêu cầu sẽ không được khai thác. Hãy tưởng tượng gửi một DELETEyêu cầu đến một APIthiết kế khi động từ này không tồn tại. Kết quả là không thể đoán trước và kết quả có thể nguy hiểm .


3
Câu trả lời của bạn đã giúp tôi. Tôi đã thử mọi cách có thể với các giải pháp cơ sở mã. Tôi đã không thử tùy chọn web.config cho đến khi tôi đọc câu trả lời của bạn. Đó là người duy nhất làm việc. Bất cứ ý tưởng tại sao? Tôi đang sử dụng API Web 2 với OData. Dẫu sao cũng xin cảm ơn! :)
Felipe Correa

1
Để tham khảo trong tương lai, gói NuGet bạn cần cho việc này là "Microsoft.AspNet.WebApi.Cors".
BrainSlugs83

2
Tôi đã làm theo tất cả câu trả lời của bạn và tôi có hai câu hỏi: Application_BeginRequest () nên được gọi ở đâu? và thứ hai, trong cùng một phương thức, .Contains ("Origin") không thực sự biên dịch với tôi, phương thức này từ đâu, String.Contains hoặc từ Linq.Contains?
meJustAndrew

2
hãy nhớ một cổng khác # tạo thành một tên miền khác, có thể là một hình ảnh xác thực. foo.com là tên miền khác với foo.com:8080
RyBolt

1
Bạn cứu mạng tôi;)
Paweł Groński

26

Câu trả lời của @ Mihai-Andrei Dinculescu là chính xác, nhưng vì lợi ích của người tìm kiếm, cũng có một điểm tinh tế có thể gây ra lỗi này.

Thêm '/' vào cuối URL của bạn sẽ ngăn EnableCors hoạt động trong mọi trường hợp (ví dụ: từ trang chủ).

Tức là điều này sẽ không hoạt động

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);

nhưng điều này sẽ làm việc:

var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);

Hiệu ứng là như nhau nếu sử dụng Thuộc tính EnableCors.


Cảm ơn!! Nó rất hữu ích.
Ankit Sahrawat

23

Tôi đã làm theo tất cả các bước trên được chỉ định bởi Mihai-Andrei Dinculescu .
Nhưng trong trường hợp của tôi, tôi cần thêm 1 bước nữa vì http TÙY CHỌN đã bị vô hiệu hóa trong Web.Config theo dòng bên dưới.

<remove name="OPTIONSVerbHandler" />

Tôi vừa xóa nó khỏi Web.Config (chỉ nhận xét như bên dưới) và Cors hoạt động như một bùa mê

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>

9

Có thể là do việc cài đặt các gói nuget Cors.

Nếu bạn gặp phải vấn đề sau khi cài đặt và kích hoạt các phần tử từ nuget, thì bạn có thể thử cài đặt lại Api web.

Từ trình quản lý gói, chạy Update-Package Microsoft.AspNet.WebApi -reinstall


Đây chính xác là nó cho tôi. Tôi đã cài đặt System.Web.Http.Cors và sau đó gỡ cài đặt, khiến WebApi không đúng phiên bản (mới được nâng cấp) trong khoảng 5.2.2 đến 5.2.3
TaeKwonJoe

7

Hãy thử điều này, để đảm bảo bạn đã cấu hình CORS chính xác:

[EnableCors(origins: "*", headers: "*", methods: "*")]

Vẫn không làm việc? Kiểm tra sự hiện diện của tiêu đề HTTP.


để kiểm tra xem nó có hoạt động hay không, tốt hơn hết là loại bỏ supportCredentials, nó cũng vô hiệu hóa cors trong một số điều kiện nhất định
harishr 16/12/14

Câu trả lời tốt nhất vì tôi không muốn bật CORS cho toàn bộ trang web của mình, chỉ một số điểm cuối nhất định. config.EnableCors()là cần thiết cho điều này là tốt.
Csaba Toth

4

Để làm cho bất kỳ giao thức CORS nào hoạt động, bạn cần có một phương thức TÙY CHỌN trên mọi điểm cuối (hoặc bộ lọc toàn cầu với phương thức này) sẽ trả về các tiêu đề đó:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

Lý do là trình duyệt sẽ gửi yêu cầu TÙY CHỌN đầu tiên để 'kiểm tra' máy chủ của bạn và xem các ủy quyền


2

Tôi bắt trường hợp tiếp theo về cors. Có lẽ nó sẽ hữu ích cho ai đó. Nếu bạn thêm tính năng 'WebDav Redirector' vào máy chủ của mình, các yêu cầu PUT và DELETE sẽ không thành công.

Vì vậy, bạn sẽ cần xóa 'WebDAVModule' khỏi máy chủ IIS của mình:

  • "Trong Cấu hình mô-đun IIS, lặp lại WebDAVModule, nếu máy chủ web của bạn có nó, thì hãy gỡ bỏ nó".

Hoặc thêm vào cấu hình của bạn:

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>


2

Tôi biết tôi sẽ đến đây rất muộn. Tuy nhiên, đối với bất kỳ ai đang tìm kiếm, tôi nghĩ tôi sẽ xuất bản những gì CUỐI CÙNG làm việc cho tôi. Tôi không khẳng định đó là giải pháp tốt nhất - chỉ có điều nó đã hoạt động.

Dịch vụ WebApi của chúng tôi sử dụng phương thức config.EnableCors (corsAttribution). Tuy nhiên, ngay cả với điều đó, nó vẫn sẽ thất bại trong các yêu cầu trước chuyến bay. Câu trả lời của @ Mihai-Andrei Dinculescu đã cung cấp manh mối cho tôi. Trước hết, tôi đã thêm mã Application_BeginRequest () của mình để xóa các yêu cầu tùy chọn. Điều đó VẪN không làm việc cho tôi. Vấn đề là WebAPI vẫn chưa thêm bất kỳ tiêu đề dự kiến ​​nào vào yêu cầu TÙY CHỌN. Việc xả nó một mình không hiệu quả - nhưng nó cho tôi một ý tưởng. Tôi đã thêm các tiêu đề tùy chỉnh sẽ được thêm thông qua web.config vào phản hồi cho yêu cầu TÙY CHỌN. Đây là mã của tôi:

protected void Application_BeginRequest()
{
  if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
  {
    Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
    Response.Headers.Add("Access-Control-Allow-Headers",
      "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
    Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    Response.Flush();
  }
}

Rõ ràng, điều này chỉ áp dụng cho các yêu cầu TÙY CHỌN. Tất cả các động từ khác được xử lý bởi cấu hình CORS. Nếu có một cách tiếp cận tốt hơn cho điều này, tôi là tất cả tai. Tôi cảm thấy như là một trò lừa gạt đối với tôi và tôi thích hơn nếu các tiêu đề được thêm tự động, nhưng đây là điều cuối cùng đã hoạt động và cho phép tôi tiếp tục.


1

Câu trả lời của @ Mihai-Andrei Dinculescu có hiệu quả với tôi, vd:

  • Thêm <httpProtocol>vào những năm web.config <system.webServer>phần
  • Trả lại phản hồi trống cho OPTIONScác yêu cầu thông qua đề cập Application_BeginRequest()trongglobal.asax

Ngoại trừ việc kiểm tra của anh Request.Headers.AllKeys.Contains("Origin")ấy KHÔNG làm việc cho tôi, bởi vì yêu cầu chứa một origing, vì vậy với chữ thường. Tôi nghĩ trình duyệt của tôi (Chrome) gửi nó như thế này cho các yêu cầu CORS.

Thay vào đó, tôi đã giải quyết vấn đề này một cách tổng quát hơn bằng cách sử dụng một biến thể không nhạy cảm của Containsséc của mình : if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {


0

Nếu bạn có các nút bảo mật \ requestFiltering trong web.config như sau:

<security>
  <requestFiltering>
    <verbs allowUnlisted="false">
      <add verb="GET" allowed="true" />
      <add verb="POST" allowed="true" />
      <add verb="PUT" allowed="true" />
      <add verb="DELETE" allowed="true" />
      <add verb="DEBUG" allowed="true" />          
    </verbs>
  </requestFiltering>

đảm bảo bạn cũng thêm cái này

<add verb="OPTIONS" allowed="true" />

0

Tôi đã thử mọi thứ tôi có thể tìm thấy trên mạng bao gồm các phương pháp đã được đưa ra cho câu trả lời này. Sau khi gần như cố gắng giải quyết vấn đề trong cả ngày, tôi đã tìm ra giải pháp hiệu quả cho mình như một cơ duyên.

trong tệp WebApiConfig trong thư mục App_Start , nhận xét tất cả các dòng mã và thêm mã sau đây:

`public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.EnableCors();
        var enableCorsAttribute = new EnableCorsAttribute("*",
                                           "Origin, Content-Type, Accept",
                                           "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);
        // Web API routes
        config.MapHttpAttributeRoutes();

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

    public class BrowserJsonFormatter : JsonMediaTypeFormatter
    {
        public BrowserJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            this.SerializerSettings.Formatting = Formatting.Indented;
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }`

0

Tôi biết rằng mọi người có thể sẽ thấy điều này rất rõ ràng lúc đầu, nhưng thực sự nghĩ về điều này. Điều này thường có thể xảy ra nếu bạn làm sai điều gì đó.

Ví dụ, tôi đã gặp vấn đề này vì tôi đã không thêm mục nhập máy chủ vào tệp máy chủ của mình. Vấn đề thực sự là độ phân giải DNS. Hoặc tôi chỉ nhận được URL cơ sở sai.

Đôi khi tôi gặp lỗi này nếu mã thông báo nhận dạng đến từ một máy chủ, nhưng tôi đang cố gắng sử dụng nó trên máy chủ khác.

Đôi khi bạn sẽ gặp lỗi này nếu bạn có tài nguyên sai.

Bạn có thể nhận được điều này nếu bạn đặt phần mềm trung gian CORS quá muộn trong chuỗi.


0

Tránh nhiều nơi kích hoạt CORS, như WebApiCOnfig.cs, phương thức GrantResourceOwnerCredentials trong nhà cung cấp và thuộc tính Header điều khiển, v.v. Dưới đây là danh sách cũng gây ra Kiểm soát truy cập cho phép xuất xứ

  1. Web có thể tương tác với DB mà bạn đã sử dụng.
  2. AWS Cloud Nếu VPC của Web API và DB khác nhau.

Mã bên dưới là nhiều hơn sau đó đủ để sửa lỗi kiểm soát truy cập cho phép xuất xứ. // Đảm bảo app.UseCors phải nằm trên dòng mã cấu hình.

   public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            //All other configurations
        }
    }

Điều này làm chậm vấn đề của tôi.


0

Vấn đề đó xảy ra khi bạn cố gắng truy cập từ một tên miền khác hoặc cổng khác.

Nếu bạn đang sử dụng Visual Studio, hãy truy cập Công cụ> Trình quản lý gói NuGet> Bảng điều khiển quản lý gói. Ở đó bạn phải cài đặt Gói NuGet Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

Sau đó, trong DỰ ÁN> App_Start> WebApiConfig, bật CORS

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        
        //Enable CORS. Note that the domain doesn't have / in the end.
        config.EnableCors(new EnableCorsAttribute("https://tiagoperes.eu",headers:"*",methods:"*"));

        ....

    }
}

Sau khi cài đặt thành công, xây dựng giải pháp và điều đó sẽ đủ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.