MVC web api: ไม่มีส่วนหัว 'Access-Control-Allow-Origin' อยู่ในทรัพยากรที่ร้องขอ


129

ฉันลองทุกอย่างที่เขียนในบทความนี้: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-apiแต่ไม่ได้ผล ฉันพยายามดึงข้อมูลจาก webAPI2 (MVC5) เพื่อใช้ในโดเมนอื่นโดยใช้ angularJS

ตัวควบคุมของฉันมีลักษณะดังนี้:

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
แบ่งปันรหัสเชิงมุมของคุณเพื่อขอ cors ด้วย
harishr

2
อาจไม่มีปัญหากับรหัสเชิงมุมของเขาเนื่องจาก CORS problams ส่วนใหญ่เป็นเพราะการกำหนดค่าเซิร์ฟเวอร์เท่านั้น
sam

ฉันมีการตั้งค่าแบบเดียวกันฉันสังเกตเห็นว่าเมื่อฉันร้องขอการดำเนินการที่ไม่มีอยู่ใน API และ WebApi กำลังส่งคืน 404 ส่วนหัว CORS หายไปและเบราว์เซอร์จะบ่น ดังนั้นมันอาจจะง่ายอย่างนั้น
Robin van der Knaap

คำตอบ:


296

คุณต้องเปิดใช้งานCORSในWeb Api ของคุณ วิธีที่ง่ายกว่าและเป็นที่ต้องการในการเปิดใช้งาน CORS ทั่วโลกคือการเพิ่มสิ่งต่อไปนี้ลงใน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>

โปรดทราบว่าวิธีการ*ที่ระบุไว้ทั้งหมดเป็นรายบุคคลแทนการใช้ *นี้เป็นเพราะมีข้อผิดพลาดเกิดขึ้นเมื่อมีการใช้

คุณยังสามารถเปิดใช้งานCORSด้วยรหัส

อัปเดตแพ็คเกจNuGet
ต่อไปนี้เป็นสิ่งจำเป็น: .Microsoft.AspNet.WebApi.Cors

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

        // ...
    }
}

จากนั้นคุณสามารถใช้[EnableCors]แอตทริบิวต์บน Actions หรือ Controllers เช่นนี้

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

หรือคุณสามารถลงทะเบียนได้ทั่วโลก

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

        // ...
    }
}

นอกจากนี้คุณยังจะต้องจัดการ preflight Options คำขอที่มีHTTP OPTIONSการร้องขอ

Web APIความต้องการที่จะตอบสนองต่อการร้องขอในการสั่งซื้อเพื่อยืนยันว่ามีการกำหนดค่าแน่นอนที่ให้การสนับสนุนOptionsCORS

ในการจัดการสิ่งนี้สิ่งที่คุณต้องทำคือส่งคำตอบที่ว่างเปล่ากลับไป คุณสามารถทำได้ภายในการกระทำของคุณหรือคุณสามารถทำได้ทั่วโลกเช่นนี้:

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

เพิ่มการตรวจสอบพิเศษนี้เพื่อให้แน่ใจว่าระบบเก่าAPIsที่ออกแบบมาเพื่อยอมรับเท่านั้นGETและPOSTคำขอจะไม่ถูกใช้ประโยชน์ ลองนึกภาพการส่งDELETEคำขอไปยังAPIออกแบบมาเมื่อนี้คำกริยาไม่ได้อยู่ ผลเป็นที่คาดเดาไม่และผลที่อาจจะเป็นอันตราย


4
คำตอบของคุณช่วยฉัน ฉันได้ลองทุกอย่างที่ทำได้ด้วยโซลูชันฐานรหัส ฉันไม่ได้ลองใช้ตัวเลือก web.config จนกว่าจะได้อ่านคำตอบของคุณ มันเป็นคนเดียวที่ได้ผล คิดว่าทำไม? ฉันใช้ Web API 2 กับ OData ขอบคุณต่อไป! :)
Felipe Correa

1
สำหรับการอ้างอิงในอนาคตแพ็คเกจ NuGet ที่คุณต้องการสำหรับสิ่งนี้คือ "Microsoft.AspNet.WebApi.Cors"
BrainSlugs83

2
ฉันได้ติดตามคำตอบของคุณทั้งหมดแล้วและฉันมีคำถามสองข้อ: Application_BeginRequest () ควรถูกเรียกใช้ที่ไหน? และประการที่สองในวิธีเดียวกัน .Contains ("Origin") ไม่ได้รวบรวมที่ฉันจริงๆวิธีนี้มาจากไหน String.Contains หรือจาก Linq.Contains?
meJustAndrew

2
จำพอร์ตที่แตกต่างกัน # ถือเป็นโดเมนที่แตกต่างกันซึ่งอาจเป็น gotcha foo.com เป็นโดเมนที่แตกต่างจาก foo.com:8080
RyBolt

2
คุณช่วยชีวิตฉัน;)
PawełGroński

26

คำตอบของ @ Mihai-Andrei Dinculescu นั้นถูกต้อง แต่เพื่อประโยชน์ของผู้ค้นหายังมีจุดที่ละเอียดอ่อนที่อาจทำให้เกิดข้อผิดพลาดนี้ได้

การเพิ่ม '/' ที่ส่วนท้ายของ URL ของคุณจะทำให้ EnableCors หยุดทำงานในทุกอินสแตนซ์ (เช่นจากหน้าแรก)

เช่นนี้จะไม่ทำงาน

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

แต่จะได้ผล:

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

ผลจะเหมือนกันหากใช้ EnableCors Attribute


ขอบคุณ !! มันเป็นประโยชน์
Ankit Sahrawat

23

ผมทำตามขั้นตอนทั้งหมดข้างต้นที่ระบุโดยMihai-อังเดร Dinculescu
แต่ในกรณีของฉันฉันต้องการอีก 1ขั้นตอนเนื่องจาก http OPTIONS ถูกปิดใช้งานในเว็บกำหนดค่าตามบรรทัดด้านล่าง

<remove name="OPTIONSVerbHandler" />

ฉันเพิ่งลบออกจาก Web.Config (เพียงแสดงความคิดเห็นด้านล่าง) และ Cors ก็ทำงานได้อย่างมีเสน่ห์

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

9

อาจเป็นเพราะการติดตั้งแพ็คเกจ Cors nuget

หากคุณประสบปัญหาหลังจากติดตั้งและเพิ่มประสิทธิภาพ cors จาก nuget คุณอาจลองติดตั้ง web Api ใหม่

จากตัวจัดการแพ็คเกจให้เรียกใช้ Update-Package Microsoft.AspNet.WebApi -reinstall


นี่คือสิ่งที่ถูกต้องสำหรับฉัน ฉันติดตั้ง System.Web.Http.Cors แล้วถอนการติดตั้งซึ่งทำให้ WebApi ผิดเวอร์ชัน (อัปเกรดใหม่) ระหว่าง 5.2.2 ถึง 5.2.3
TaeKwonJoe

7

ลองทำเช่นนี้เพื่อให้แน่ใจว่าคุณกำหนดค่า CORS อย่างถูกต้อง:

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

ยังไม่ทำงาน? ตรวจสอบการมีอยู่ของส่วนหัว HTTP


เพื่อตรวจสอบว่าใช้งานได้หรือไม่ควรลบ supportCredentials ออกด้วยจะปิดการใช้งาน cors ในบางเงื่อนไข
harishr

คำตอบที่ดีที่สุดเพราะฉันไม่ต้องการเปิดใช้งาน CORS สำหรับทั้งไซต์ของฉันเพียงแค่จุดสิ้นสุดที่แน่นอน config.EnableCors()เป็นสิ่งจำเป็นสำหรับสิ่งนี้เช่นกัน
Csaba Toth

4

ในการทำให้โปรโตคอล CORS ทำงานได้คุณต้องมีเมธอด OPTIONS ในทุกจุดสิ้นสุด (หรือตัวกรองส่วนกลางด้วยวิธีนี้) ซึ่งจะส่งคืนส่วนหัวเหล่านั้น:

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

เหตุผลก็คือเบราว์เซอร์จะส่งคำขอ OPTIONS ก่อนเพื่อ 'ทดสอบ' เซิร์ฟเวอร์ของคุณและดูการอนุญาต


3

ฉันรู้ว่าฉันมาสายมาก อย่างไรก็ตามสำหรับใครก็ตามที่กำลังค้นหาฉันคิดว่าฉันจะเผยแพร่สิ่งที่ได้ผลในที่สุด ฉันไม่ได้อ้างว่านี่เป็นทางออกที่ดีที่สุด - เพียงอย่างเดียวที่ใช้ได้ผล

บริการ WebApi ของเราใช้เมธอด config.EnableCors (corsAttribute) อย่างไรก็ตามแม้ว่าจะเป็นเช่นนั้น แต่ก็ยังคงล้มเหลวในคำขอก่อนการบิน คำตอบของ @ Mihai-Andrei Dinculescu ให้เบาะแสสำหรับฉัน ก่อนอื่นฉันเพิ่มรหัส Application_BeginRequest () ของเขาเพื่อล้างคำขอตัวเลือก ยังคงไม่ได้ผลสำหรับฉัน ปัญหาคือ WebAPI ยังไม่ได้เพิ่มส่วนหัวที่คาดไว้ในคำขอ OPTIONS การล้างเพียงอย่างเดียวไม่ได้ผล - แต่มันทำให้ฉันมีความคิด ฉันเพิ่มส่วนหัวที่กำหนดเองที่จะเพิ่มผ่าน web.config ในการตอบสนองสำหรับคำขอ OPTIONS นี่คือรหัสของฉัน:

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();
  }
}

เห็นได้ชัดว่าสิ่งนี้ใช้ได้กับคำขอ OPTIONS เท่านั้น คำกริยาอื่น ๆ ทั้งหมดได้รับการจัดการโดยการกำหนดค่า CORS ถ้ามีแนวทางที่ดีกว่านี้ฉันก็หูผึ่ง รู้สึกเหมือนเป็นการโกงสำหรับฉันและฉันต้องการถ้าเพิ่มส่วนหัวโดยอัตโนมัติ แต่นี่คือสิ่งที่ได้ผลในที่สุดและอนุญาตให้ฉันเดินหน้าต่อไป


2

ฉันจับกรณีต่อไปเกี่ยวกับ cors บางทีมันอาจจะมีประโยชน์กับใครบางคน หากคุณเพิ่มคุณสมบัติ 'WebDav Redirector' ให้กับเซิร์ฟเวอร์ของคุณคำขอ PUT และ DELETE จะล้มเหลว

ดังนั้นคุณจะต้องลบ 'WebDAVModule' ออกจากเซิร์ฟเวอร์ IIS ของคุณ:

  • "ในการกำหนดค่าโมดูล IIS ให้วน WebDAVModule หากเว็บเซิร์ฟเวอร์ของคุณมีอยู่ให้ลบออก"

หรือเพิ่มใน config ของคุณ:

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


1

คำตอบของ @ Mihai-Andrei Dinculescu ใช้ได้ผลกับฉันเช่น:

  • การเพิ่ม<httpProtocol>ใน<system.webServer>ส่วนของ web.config
  • ส่งคืนการตอบกลับที่ว่างเปล่าสำหรับOPTIONSคำขอผ่านทางที่ระบุไว้Application_BeginRequest()ในglobal.asax

ยกเว้นว่าเช็คของเขาใช้Request.Headers.AllKeys.Contains("Origin")ไม่ได้สำหรับฉันเพราะคำขอorigingมีตัวพิมพ์เล็กอยู่ด้วย ฉันคิดว่าเบราว์เซอร์ของฉัน (Chrome) ส่งแบบนี้สำหรับคำขอ CORS

ฉันแก้ไขสิ่งนี้เพิ่มเติมเล็กน้อยโดยใช้ตัวแปรที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ของContainsเช็คของเขาแทน: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {


0

หากคุณมีโหนด security \ requestFiltering ใน web.config ของคุณดังนี้:

<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>

อย่าลืมเพิ่มสิ่งนี้ด้วย

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

0

ฉันได้ลองทุกอย่างที่หาได้จากอินเทอร์เน็ตรวมถึงวิธีการที่ได้รับคำตอบนี้ หลังจากพยายามแก้ปัญหามาทั้งวันแล้วฉันก็พบวิธีแก้ปัญหาที่ได้ผลสำหรับฉันอย่างมีเสน่ห์

ในไฟล์WebApiConfigในโฟลเดอร์App_Startแสดงความคิดเห็นทุกบรรทัดของโค้ดและเพิ่มรหัสต่อไปนี้:

`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

ฉันรู้ว่าผู้คนอาจจะพบสิ่งนี้ชัดเจนในตอนแรก แต่ลองคิดถึงเรื่องนี้จริงๆ สิ่งนี้มักเกิดขึ้นได้หากคุณทำอะไรผิดพลาด

ตัวอย่างเช่นฉันมีปัญหานี้เพราะฉันไม่ได้เพิ่มรายการโฮสต์ในไฟล์โฮสต์ของฉัน ปัญหาที่แท้จริงคือการแก้ปัญหา DNS หรือฉันเพิ่งเข้าใจผิด

บางครั้งฉันได้รับข้อผิดพลาดนี้หากโทเค็นประจำตัวมาจากเซิร์ฟเวอร์หนึ่ง แต่ฉันกำลังพยายามใช้กับอีกเซิร์ฟเวอร์หนึ่ง

บางครั้งคุณจะได้รับข้อผิดพลาดนี้หากคุณใช้ทรัพยากรไม่ถูกต้อง

คุณอาจได้รับสิ่งนี้หากคุณใส่มิดเดิลแวร์ CORS ในสายโซ่เกินไป


0

หลีกเลี่ยงสถานที่หลายแห่งที่เปิดใช้งาน CORS เช่น WebApiCOnfig.cs เมธอด GrantResourceOwnerCredentials ในแอตทริบิวต์ส่วนหัวของผู้ให้บริการและคอนโทรลเลอร์เป็นต้นด้านล่างนี้คือรายการที่ทำให้เกิด Access Control Allow Origin

  1. เว็บมีปัญหาในการโต้ตอบกับ DB ที่คุณใช้
  2. AWS Cloud หาก VPC ของ Web API และ DB แตกต่างกัน

โค้ดด้านล่างนี้มีมากพอที่จะแก้ไขการควบคุมการเข้าถึงอนุญาตให้กำเนิด // ตรวจสอบให้แน่ใจว่าแอป UsCors ควรอยู่บนสุดของบรรทัดรหัสของการกำหนดค่า

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

สิ่งนี้ทำให้ปัญหาของฉันช้าลง


0

ปัญหานั้นเกิดขึ้นเมื่อคุณพยายามเข้าถึงจากโดเมนอื่นหรือพอร์ตอื่น

หากคุณใช้ Visual Studio ให้ไปที่ Tools> NuGet Package Manager> Package Manager Console คุณต้องติดตั้ง NuGet Package Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

จากนั้นใน PROJECT> App_Start> WebApiConfig ให้เปิดใช้งาน 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:"*"));

        ....

    }
}

เมื่อติดตั้งสำเร็จแล้วให้สร้างโซลูชันและควรจะเพียงพอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.