Bir bilgisayar mühendisi için programlama dili, öğrendiklerini sınadığı, deneyler yaptığı bir laboratuardır ve mühendisler deneylerini, kestiremedikleri sonuçları gözlemlemek için değil, öngördükleri sonuçları doğrulamak için yapar...

Ajax 'İzin Verilmedi' Hatası

Ajax ile yapılan istekler bu hatayı neden verir? 'İzin Verilmedi' hata nasıl giderilir?

Bir ajax scripti, sadece indirildiği site üzerindeki bir sayfaya veri iletebilir ve oradan veri çekebilir. Başka bir siteye veri iletmesi ya da başka bir siteden veri çekmesi normal şartlarda mümkün değil. Bu engel, çapraz site scpritlerini (xss) önlemek için konmuş olsa da www önekine sahip bir konumdan, bu öneke sahip olmayan, ancak aynı siteye işaret eden başka bir konuma erişime izin vermeyerek problem yaratabiliyor.

Normalde XMLHttpRequest nesnesine alan adı içeren bir adres zaten verilmez. Verilen adres, o an bulunulan konumda geçerli olan bir sayfa adresidir. Örneğin "http://www.atasoyweb.net/birdizin/index.php" sayfasındaki bir XMLHttpRequest nesnesinden "anketler.php" dosyası istenirse nesne, "http://www.atasoyweb.net/birdizin/anketler.php"dosyasını isteyecektir. Ancak her konum her zaman var olmak zorunda değil. Örneğin adres çubuğuna bakarsanız şu an "javascript-ajax-k14s0" klasörü içerisinde görünüyorsunuz. (Blogdaki son güncellemeden sonra bağlantılar değiştirildi.) Ama gerçekte sunucuda "javascript-ajax-k14s0" klasörü de "ajax-izin-verilmedi-hatasi-y85.html" dosyası da yok. İşte bu tip sayfalarda işler karışıyor. İşin kötü tarafı, her dosya veya dizin, kök dizine eşit uzaklıkta olmak zorunda da değil. Dolayısıyla, XMLHttpRequest nesnesini sunucuda istediğiniz konumda gezdirmeniz zor. Bu durumda nesneden istettiğimiz sayfaların tam adresini girmek zorunda kalırız. Sitenin dışına çıkılmaması koşuluyla XMLHttpRequest nesnesi tam adres alıp, o adrese istek yollayabilir. Ancak aynı siteye işaret ediyor olmasına rağmen www öneki yazılmadan girilmiş bir sayfada çalışan bir XMLHttpRequest nesnesinden, www önekli bir adrese istek yollaması istendiğinde nesne, "İzin verilmedi" şeklinde oldukça açıklayıcı(!) bir hata döndrürerek bu isteği reddeder...

AtasoyBlogda yorumları ve anket oylamalarını ajax ile almaya çalışırken karşılaştığım bu problemi çözmek için aklıma gelen iki çözümü de aşağıya yazıyorum. Hangisini isterseniz kullanabilirsiniz.

Çözüm 1

Hangi konumda olursanız olun, bulunduğunuz konumun, ajax ile isteteceğiniz sayfayanın dizinine olan uzaklığını hesaplayabilirsiniz. Hesaplayalım:

$_SERVER['REQUEST_URI'] o an bulunulan konumu döndürür. Örneğin XMLHttpRequest nesnesinin çalıştırıldığı sayfa "http://www.atasoyweb.net/dizin1/dizin2/sayfa.html" ve nesnenin isteyeceği sayfa "baskadizin/baska.html" (kök dizindeki konum) olsun. Bu durumda $_SERVER['REQUEST_URI'] "/dizin1/dizin2/sayfa.html" değerini taşır. Bu değerdeki "/" karakterlerinin sayısının bir eksiği kök dizine olan uzaklıktır. Bulunan uzaklık kadar geri gidilerek kök dizine ulaşılır ve bu konuma istenen sayfanın konumu eklenir. Verdiğimiz örnek için sonuç "../../baskadizin/baska.html" olur. Bu adres XMLHttpRequest nesnesine istetilebilir ve problem de giderilmiş olur.

$uzaklik = substr_count($_SERVER['REQUEST_URI'],"/")+1;
$kokdizin = str_repeat("../", $uzaklik);
$istenecek = $kokdizin."baskadizin/baska.html";

Bu çözümü uygulamak kolay değil. Çünkü istenecek sayfanın adresi değişken olmuş oldu ve her seferinde XMLHttpRequest nesnesine yeniden yollanması gerekiyor. PHP ile bu değeri içeren gizli bir eleman yazılıp html dosyasına eklenirse javascript fonksiyonları da bu değeri o gizli elemanın içeriğinden alabilir.

echo "<input id=\"sayfa\" type=\"hidden\" value=\"$istenecek\">"; //php, gönderici
var istenecek = document.getElementById('sayfa').value;  //javascript, alıcı

Çözüm 2

1. yöntem yerine yukarıda değindiğimiz gibi XMLHttpRequest nesnesine site adresini de içeren sabit bir sayfa adresi girebiliriz. "İzin verilmedi" hatasının gidermek için de ajax kullanan sayfaların bulunduğu konumlara gelen tüm istekleri, www önekli adreslere yönlendirerek (veya tam tersi; www öneksiz adreslere yönlendirerek) problemi çözmüş oluruz. Bu daha kolay...

Bir siteye gelen ve www öneki içermeyen istekleri, www önekli konumlara kalıcı (301) olarak yönlendiren kod aşağıda. Mantığı düzenli ifadelere dayanıyor. Bunları da başka bir yazıda işleriz artık...

RewriteEngine On
RewriteCond %{HTTP_HOST} ^atasoyweb.net
RewriteRule (.*) http://www.atasoyweb.net/$1 [R=301,L]

Bir hatırlatma; kodlar .htaccess dosyasına yazılmalı ve bu kodları içeren .htaccess dosyası, ajax fonksiyonları barındıran scripti kullanacak dosyaların bulunduğu konuma konmalı. İstenirse kök dizine atılarak, tüm site için etkin olması da sağlanabilir...

Sayfayı
Yayın tarihi: 02 Mayıs 2010 Pazar, 16:14
Anahtar kelimeler: ajax, izin verilmedi hatası, xss, cross site scripting, xmlhttprequest

Yorum Gönder

 
Yorumunuzu -1. yoruma yanıt olarak gönderiyorsunuz. Yanıtlamayı iptal etmek için buraya tıklayabilirsiniz.

 

Yorumlar

Onaylanmış yorum bulunmuyor.
 
 
Sayfa 37 sorgu ile 0.004 saniyede oluşturuldu.
Atasoy Blog v4 © 2008-2017 Hüseyin Atasoy