ASP.NET – WEB API- CROSS DOMAIN – JQUERY AJAX – ACCESS CONTROL ALLOW ORIGIN HATASI
Merhabalar , Bu yazımızda cross domain hatası ve nedenleri ile alakalı durumlardan kısaca bahsedeceğim.
Öncelikle Cross domain hatası nedir ?
- Başka bir dominden wep api ye ajax request yapılırken tarayıcı güvenlik gereği sayfayı engeller.
- Bu kısıtlamaya same-origin policy denir.
Cross Domain olması için ,
- Aynı domain farklı port
- farklı dominlerin olması
- Farklı protokollerde olması http,https gibi.
CORS Nedir?
Cross-Origin Resource Sharing (Kökenler arası kaynak paylaşımı) anlamına gelen CORS, web tarayıcısı tarafından yönetilen ve ek HTTP başlıkları kullanılarak, bir kökende çalışan web uygulamasının, farklı bir kökende yer alan web uygulamasına erişim izni kontrolünü sağlayan mekanizmadır. Web uygulaması, internet tarayıcısı üzerinden farklı bir kökene (protokol, domain ve port) herhangi bir istek gönderirse cross-origin HTTP isteği oluşturmuş olur.
Örneğin, http://domain-a.com
üzerinde yer alan bir web uygulamasının JavaScript tarafından ajax isteği göndererek, http://domain-b.com
‘a erişmesi bir cross origin isteğidir.
Not: Eğer frontend (browser) tarafından değil de backend tarafından (Örneğin C# koduyla) domain-b.com’a erişseydi bu bir cross origin istek olmayacaktı.
Wep Api Projemizide bu hatayı çözmek ve gerekli izinleri vermek için yapmamız gereken işlemler
Öncelik olarak projemize Nuget üzerinden System.Web.Http.Cors; dll ini indrelim.
1.Yöntem : WebApiConfig.cs ten ayarlamalarımızı yapmak.
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Formatting; using System.Net.Http.Headers; using System.Web.Http; using System.Web.Http.Cors; namespace GET_POST_PUT_DELETE { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); //EnableCorsAttribute cors = new EnableCorsAttribute("http://localhost:3583", "*", "*"); //EnableCorsAttribute cors = new EnableCorsAttribute("http://localhost:3583,http://localhost:3584", "*", "*"); EnableCorsAttribute cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); } } }
EnableCorsAttribute sınıfına giriş parametresi olarak domain-origin , headers,methods verebiliriz , tüm herşeye izin vermek için * şareti ile tanımlama yapmamız yeterli olacaktır.
Bu ayarlama ile artık farklı domaindeki sitelerden AJAX Requestler başarılı şekilde çalışabileceklerdir.
2.Yöntem
Eğer bu iznin tüm proje genelinde olmasını istemiyor isek bunu bir Attribute olarak Controller veya Action da tanımlayıp kullanabiliriz.
Yapmamız gereken tek şey örnek koddakı gibi controller veya action üzerine EnableCors attribute ünü tanımlamak.
Örnek Kod:
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using System.Web.Http.Cors; namespace GET_POST_PUT_DELETE.Controllers { [EnableCors("http://localhost:3583","*","")] public class EmployeesController : ApiController { private ModelContext db = new ModelContext(); public IQueryable<Employees> Gets() { return db.Employees; } } }
3. Yönetem: Kendi MediaTypeFormatter ımızı yaparak bu özelliği eklemek.
Örneğimizde MediaTypeFormatter classını WebApiConfig.cs dosyası içerisinde yaptım.
JsonFormatterdan miras alarak yaptığımız için öncelik olarak JsonFormater ı remove edip kendi formatter ımızı ekleyeceğiz.
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Formatting; using System.Net.Http.Headers; using System.Web.Http; using System.Web.Http.Cors; namespace GET_POST_PUT_DELETE { public class MyJsonFormatter : JsonMediaTypeFormatter { public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) { base.SetDefaultContentHeaders(type, headers, mediaType); headers.Add("Access-Control-Allow-Origin", "*"); } } public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; config.Formatters.Remove(config.Formatters.JsonFormatter); config.Formatters.Add(new MyJsonFormatter()); //EnableCorsAttribute cors = new EnableCorsAttribute("http://localhost:3583,http://localhost:3584", "*","*"); //config.EnableCors(cors); } } }
MediaTypeFormatter kodlarımız :