MVC web api: Header 'Access-Control-Allow-Origin' tidak ada pada sumber daya yang diminta

128

Saya mencoba semua yang ditulis dalam artikel ini: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api , tetapi tidak ada yang berhasil. Saya mencoba untuk mendapatkan data dari webAPI2 (MVC5) untuk digunakan di domain lain menggunakan angularJS.

controller saya terlihat seperti ini:

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;

        }      
    }
}
Noa Gani
sumber
1
Juga bagikan kode sudut Anda untuk meminta kor
harishr
2
Mungkin tidak ada masalah dengan kode sudutnya karena sebagian besar masalah CORS hanya karena konfigurasi server
sam
Saya memiliki pengaturan yang sama, saya perhatikan bahwa ketika saya meminta tindakan yang tidak ada pada API, dan WebApi mengembalikan 404, header CORS hilang dan browser akan mengeluh. Jadi, mungkin sesederhana itu.
Robin van der Knaap

Jawaban:

296

Anda perlu mengaktifkan CORS di Api Web Anda . Cara yang lebih mudah dan lebih disukai untuk mengaktifkan CORS secara global adalah dengan menambahkan yang berikut ke 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>

Harap dicatat bahwa Metode semua ditentukan secara individual, alih-alih menggunakan *. Ini karena ada bug yang terjadi saat menggunakan *.

Anda juga dapat mengaktifkan CORS dengan kode.

Memperbarui
Berikut nuget paket diperlukan: Microsoft.AspNet.WebApi.Cors.

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

        // ...
    }
}

Kemudian Anda dapat menggunakan [EnableCors]atribut pada Actions atau Controllers seperti ini

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

Atau Anda dapat mendaftarkannya secara global

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

        // ...
    }
}

Anda juga perlu menangani Options permintaan preflight dengan HTTP OPTIONSpermintaan.

Web APIperlu menanggapi Optionspermintaan untuk mengonfirmasi bahwa permintaan memang dikonfigurasikan untuk mendukung CORS.

Untuk mengatasinya, yang perlu Anda lakukan hanyalah mengirim respons kosong kembali. Anda dapat melakukan ini di dalam tindakan Anda, atau Anda dapat melakukannya secara global seperti ini:

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

Pemeriksaan tambahan ini ditambahkan untuk memastikan bahwa lama APIsyang dirancang hanya untuk menerima GETdan POSTpermintaan tidak akan dieksploitasi. Bayangkan mengirim DELETEpermintaan ke APIdirancang ketika kata kerja ini tidak ada. Hasilnya tidak dapat diprediksi dan hasilnya mungkin berbahaya .

Mihai-Andrei Dinculescu
sumber
4
Jawaban Anda membantu saya. Saya telah mencoba semua yang saya bisa dengan solusi basis kode. Saya tidak mencoba opsi web.config sampai saya membaca jawaban Anda. Itu satu-satunya yang berhasil. Ada yang tahu kenapa? Saya menggunakan Web API 2 dengan OData. Bagaimanapun, terima kasih! :)
Felipe Correa
1
Untuk referensi di masa mendatang, paket NuGet yang Anda butuhkan untuk ini adalah "Microsoft.AspNet.WebApi.Cors".
BrainSlugs83
2
Saya telah mengikuti semua jawaban Anda dan saya punya dua pertanyaan: Di mana Application_BeginRequest () harus dipanggil? dan kedua, dalam metode yang sama, .Contains ("Origin") tidak benar-benar mengkompilasi pada saya, dari mana metode ini, String.Contains, atau dari Linq.Contains?
meJustAndrew
2
ingat porta yang berbeda # membentuk domain yang berbeda, yang bisa berupa gotcha. foo.com adalah domain yang berbeda dari foo.com:8080
RyBolt
2
Anda menyelamatkan hidup saya;)
Paweł Groński
26

Jawaban @ Mihai-Andrei Dinculescu benar, tetapi untuk kepentingan pencari, ada juga titik halus yang dapat menyebabkan kesalahan ini.

Menambahkan '/' di akhir URL Anda akan menghentikan EnableCors dari bekerja dalam semua hal (misalnya dari beranda).

Yaitu Ini tidak akan berfungsi

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

tetapi ini akan berhasil:

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

Efeknya sama jika menggunakan Atribut EnableCors.

HokiJ
sumber
Terima kasih!! Itu sangat membantu.
Ankit Sahrawat
23

Saya mengikuti semua langkah di atas yang ditunjukkan oleh Mihai-Andrei Dinculescu .
Tetapi dalam kasus saya, saya perlu 1 langkah lagi karena http OPSI dinonaktifkan di Web.Config oleh baris di bawah ini.

<remove name="OPTIONSVerbHandler" />

Saya baru saja menghapusnya dari Web.Config (komentar saja seperti di bawah ini) dan Cors berfungsi seperti pesona

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
AlbertSY
sumber
9

Mungkin karena pemasangan paket nuget Cors.

Jika Anda menghadapi masalah setelah menginstal dan mengaktifkan kors dari nuget, maka Anda dapat mencoba menginstal ulang web Api.

Dari manajer paket, jalankan Update-Package Microsoft.AspNet.WebApi -reinstall

Bimal Das
sumber
Ini tepat untuk saya. Saya menginstal System.Web.Http.Cors dan kemudian dihapus, yang meninggalkan WebApi pada versi yang salah (baru ditingkatkan) antara 5.2.2 dan 5.2.3
TaeKwonJoe
7

Coba ini, untuk memastikan Anda mengkonfigurasi CORS dengan benar:

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

Masih tidak bekerja? Periksa keberadaan tajuk HTTP.

Andrei
sumber
untuk memeriksa apakah ini berfungsi, lebih baik untuk menghapus supportCredentials juga, itu menonaktifkan kors dalam kondisi tertentu
harishr
Jawaban terbaik karena saya tidak ingin mengaktifkan CORS untuk seluruh situs saya, hanya titik akhir tertentu. config.EnableCors()diperlukan untuk ini juga.
Csaba Toth
4

Agar protokol CORS dapat berfungsi, Anda harus memiliki metode OPSI di setiap titik akhir (atau filter global dengan metode ini) yang akan mengembalikan tajuk tersebut:

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

Alasannya adalah bahwa browser akan terlebih dahulu mengirim permintaan OPSI untuk 'menguji' server Anda dan melihat otorisasi

sam
sumber
2

Saya menangkap kasus selanjutnya tentang cors. Mungkin itu akan bermanfaat bagi seseorang. Jika Anda menambahkan fitur 'WebDav Redirector' ke server Anda, permintaan PUT dan DELETE gagal.

Jadi, Anda harus menghapus 'WebDAVModule' dari server IIS Anda:

  • "Di Konfigurasi modul IIS, luruskan modul WebDAV, jika server web Anda memilikinya, lalu hapus".

Atau tambahkan ke konfigurasi Anda:

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

Andrey R
sumber
2

Saya tahu saya akan datang selarut ini. Namun, bagi siapa pun yang mencari, saya pikir saya akan menerbitkan apa yang AKHIRNYA bekerja untuk saya. Saya tidak mengklaim itu solusi terbaik - hanya saja itu berhasil.

Layanan WebApi kami menggunakan metode config.EnableCors (corsAttribute). Namun, bahkan dengan itu, masih akan gagal pada permintaan pra-penerbangan. Jawaban @ Mihai-Andrei Dinculescu memberikan petunjuk bagi saya. Pertama-tama, saya menambahkan kode Application_BeginRequest () untuk menyiram permintaan opsi. MASIH tidak bekerja untuk saya. Masalahnya adalah bahwa WebAPI masih belum menambahkan header yang diharapkan ke permintaan OPSI. Membilasnya saja tidak berhasil - tetapi itu memberi saya ide. Saya menambahkan header khusus yang kalau tidak akan ditambahkan melalui web.config ke respons untuk permintaan OPSI. Ini kode saya:

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

Jelas, ini hanya berlaku untuk permintaan PILIHAN. Semua kata kerja lainnya ditangani oleh konfigurasi CORS. Jika ada pendekatan yang lebih baik untuk ini, saya semua telinga. Rasanya seperti curang bagi saya dan saya lebih suka jika header ditambahkan secara otomatis, tetapi inilah yang akhirnya berhasil dan memungkinkan saya untuk melanjutkan.

John Groft
sumber
1

Jawaban @ Mihai-Andrei Dinculescu bekerja untuk saya, misalnya:

  • Menambahkan <httpProtocol>di web.config<system.webServer> bagian
  • Mengembalikan respons kosong untuk OPTIONSpermintaan melalui yang disebutkan Application_BeginRequest()diglobal.asax

Kecuali bahwa ceknya Request.Headers.AllKeys.Contains("Origin")TIDAK berfungsi untuk saya, karena permintaan berisi origing, jadi dengan huruf kecil. Saya pikir browser saya (Chrome) mengirimkannya seperti ini untuk permintaan CORS.

Saya memecahkan masalah ini sedikit lebih umum dengan menggunakan varian case sensitive dari Containsceknya sebagai gantinya: if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {

Bart
sumber
0

Jika Anda memiliki titik keamanan \ requestFiltering di web.config Anda sebagai berikut:

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

pastikan Anda menambahkan ini juga

<add verb="OPTIONS" allowed="true" />
ozz
sumber
0

Saya telah mencoba semua yang dapat saya temukan di internet termasuk metode yang telah diberikan pada jawaban ini. Setelah hampir mencoba menyelesaikan masalah sepanjang hari, saya menemukan solusi yang berhasil bagi saya seperti pesona.

dalam file WebApiConfig di folder App_Start , komentari semua baris kode dan tambahkan kode berikut:

`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");
        }
    }`
Yagnesh Khamar
sumber
0

Saya tahu bahwa orang mungkin akan menemukan ini sangat jelas pada awalnya, tetapi benar-benar memikirkannya. Ini bisa sering terjadi jika Anda melakukan kesalahan.

Misalnya, saya mengalami masalah ini karena saya tidak menambahkan entri host ke file host saya. Masalah sebenarnya adalah resolusi DNS. Atau saya baru saja salah URL dasar.

Terkadang saya mendapatkan kesalahan ini jika token identitas berasal dari satu server, tetapi saya mencoba menggunakannya di server lain.

Terkadang Anda akan mendapatkan kesalahan ini jika sumber dayanya salah.

Anda mungkin mendapatkan ini jika Anda meletakkan middleware CORS terlambat di rantai.

Bluebaron
sumber
0

Hindari beberapa tempat yang memungkinkan CORS, Seperti WebApiCOnfig.cs, metode GrantResourceOwnerCredentials dalam atribut provider dan Controller Header dll. Di bawah ini adalah daftar yang juga menyebabkan Access Control Allow Origin

  1. Web mengalami kesulitan berinteraksi dengan DB yang Anda gunakan.
  2. AWS Cloud Jika VPC Web API dan DB berbeda.

Kode di bawah ini lebih dari cukup untuk memperbaiki izin akses kontrol asal. // Pastikan app.UseCors harus berada di atas baris kode konfigurasi.

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

Ini memperlambat masalah saya.

Sharad
sumber
0

Masalah itu terjadi ketika Anda mencoba mengakses dari domain atau port yang berbeda.

Jika Anda menggunakan Visual Studio, kemudian pergi ke Tools> NuGet Package Manager> Package Manager Console. Di sana Anda harus menginstal Paket NuGet Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

Kemudian, di PROJECT> App_Start> WebApiConfig, aktifkan 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:"*"));

        ....

    }
}

Setelah terinstal dengan sukses, bangun solusi dan itu sudah cukup

Tiago Martins Peres 李大仁
sumber