Защо това заобиколно решение за заявка между домейни работи?

В тази статия на Джон Ресиг той се занимава със списък с размер на речник думи с javascript и той зарежда съдържанието чрез ajax от CDN.

Думите се зареждат с нови редове, разделящи думите. След това той казва, че кръстосаният домейн се проваля:

Има обаче проблем: Не можем да заредим нашия речник от CDN! Тъй като CDN се намира на друг сървър (или на друг поддомейн, какъвто е случаят тук), ние сме оставени на милостта на политиката на браузъра за различни източници, забраняваща тези видове заявки. Не всичко обаче е загубено - с просто ощипване на речниковия файл можем да го заредим в различни домейни.

Първо, заменяме всички крайни редове в речниковия файл с интервал. Второ, обгръщаме целия ред с израз JSONP. Така крайният резултат изглежда така:

dictLoaded('aah aahed aahing aahs aal... zyzzyvas zzz');

Това ни позволява да направим Ajax заявка за файла и да го накараме да работи, както се очаква - като същевременно се възползваме от цялото кеширане и компресия, предоставени от браузъра.

Така че, ако чета това правилно, простото добавяне на неговия метод dictLoaded('original content') само около оригиналното съдържание кара заявката на ajax да не се провали.

Това (превръщането му във функция + param) наистина ли е всичко, което е необходимо? и защо JSONP решава проблема с ограничението на достъпа между домейни?


person Kristian    schedule 07.05.2012    source източник


Отговори (3)


таговете <script> могат да зареждат всеки JS файл отвсякъде (дори между домейн). Хубавото, което идва с него, е, че кодът вътре в този скрипт също се изпълнява, следователно, метод за заобикаляне на ограниченията между домейни.

Проблемът е, че когато кодът се изпълни, той се изпълнява в глобалния обхват. така че имайки този код:

var test = 'foo'

ще създаде променлива test в глобалния обхват.

За да смекчите това, използвате enclose отговора във функция. Това е "P" в "JSONP", което означава "подложка". Това затваря вашия отговор в извикване на функция.

Така че, ако вашата чужда писменост има:

myFunction({
    test : 'foo'
});

Той извиква myFunction и предава обект с ключ test, който има стойност foo. Функцията за получаване ще изглежда така:

function myFunction(data){
    //"data.test" is "foo"
}

Сега успешно заобиколихме ограничението между домейни. Необходимите основни части са:

  • функцията за получаване (която може да бъде динамично създадена и изхвърлена след употреба)
  • "подплатения" JSON отговор
person Joseph    schedule 07.05.2012
comment
добър отговор, благодаря. Тъй като маркерът на скрипта се зарежда със страницата, как използването на маркер на скрипт замества традиционното повикване на ajax, при което повикването на ajax се задейства от някакво събитие? - person Kristian; 07.05.2012
comment
@Kristian AJAX е ограничен от политиката за същия произход, която ограничава комуникацията между домейни, освен когато се използва споделяне на ресурси от кръстосан произход (CORS). CORS се нуждае от сървъра да бъде настроен да позволява CORS заявки. JSONP обаче не го прави. Той просто зарежда всеки скрипт и го изпълнява. Това е като чиста магия от страна на клиента - без намеса от задния край. - person Joseph; 07.05.2012
comment
Съжалявам, сигурно съм формулирал въпроса си неясно. преформулиран: методът на маркера jsonp/script не е ли ограничен до изпълнение по време на първоначалното зареждане на страницата? като има предвид, че json заявките от ajax се случват, когато дадено събитие го задейства.. как да съгласувам тази разлика във времето? - person Kristian; 07.05.2012
comment
@Kristian да, JSONP може да бъде иницииран по всяко време. просто заредете необходимите скриптове във формат JSONP. Те също са асинхронни. - person Joseph; 07.05.2012

Това (превръщането му във функция + param) наистина ли е всичко, което е необходимо?

да

и защо това решава проблема с ограничението за достъп между домейни?

Трябва да прочетете за JSONP. Идеята е, че сега можете да включите <script> таг, динамично сочещ към ресурса, вместо да изпращате AJAX заявка (което е забранено). И тъй като сте обвили съдържанието с име на функция, тази функция ще бъде изпълнена и предадена като аргумент JSON обекта. Така че всичко, което остава за вас, е да дефинирате тази функция.

person Darin Dimitrov    schedule 07.05.2012

Това се дължи на изявлението JSONP, което добави той.

„JSON с подложка“ е допълнение към основния формат на данните JSON. Той предоставя метод за изискване на данни от сървър в различен домейн, нещо, което е забранено от типичните уеб браузъри поради политиката за същия произход.

Това работи чрез инжектиране на скриптов елемент.

JSONP има смисъл само когато се използва със скриптов елемент. За всяка нова JSONP заявка браузърът трябва да добави нов елемент или да използва повторно съществуващ. Първата опция - добавяне на нов елемент на скрипт - се извършва чрез динамична манипулация на DOM и е известна като инжектиране на елемент на скрипт. Елементът се инжектира в HTML DOM, като URL адресът на желаната JSONP крайна точка е зададен като атрибут "src". Това динамично инжектиране на елемент на скрипт обикновено се извършва от помощна библиотека на javascript. jQuery и други рамки имат jsonp помощни функции; има и самостоятелни опции.

Източник: http://en.wikipedia.org/wiki/JSONP

person Josh Mein    schedule 07.05.2012