Czy mogę wysłać żądanie JSONP między domenami w JavaScript bez korzystania z jQuery lub innej zewnętrznej biblioteki? Chciałbym użyć samego JavaScript, a następnie przeanalizować dane i uczynić z nich obiekt, aby móc go używać. Czy muszę korzystać z zewnętrznej biblioteki? Jeśli nie, jak mogę to zrobić?
javascript
jsonp
Dave
źródło
źródło
Odpowiedzi:
źródło
foo(payload_of_json_data)
:, chodzi o to, że po załadowaniu do tagu skryptu wywołuje funkcję foo z ładunkiem już jako obiekt javascript i nie jest konieczne żadne analizowanie.Lekki przykład (z obsługą onSuccess i onTimeout). Jeśli potrzebujesz, musisz podać nazwę zwrotną w adresie URL.
Przykładowe użycie:
W GitHub: https://github.com/sobstel/jsonp.js/blob/master/jsonp.js
źródło
Co to jest JSONP?
Ważną rzeczą do zapamiętania w przypadku jsonp jest to, że w rzeczywistości nie jest to protokół ani typ danych. Jest to po prostu sposób na załadowanie skryptu w locie i przetworzenie skryptu wprowadzanego na stronę. W duchu JSONP oznacza to wprowadzenie nowego obiektu javascript z serwera do aplikacji / skryptu klienta.
Kiedy potrzebny jest JSONP?
Jest to jedna z metod umożliwiania jednej domenie asynchronicznego dostępu do danych z innej domeny / przetwarzania ich na tej samej stronie. Przede wszystkim służy do przesłonięcia ograniczeń CORS (Cross Origin Resource Sharing), które wystąpiłyby w przypadku żądania XHR (ajax). Ładowanie skryptów nie podlega ograniczeniom CORS.
Jak to jest zrobione
Wprowadzenie nowego obiektu javascript z serwera można zaimplementować na wiele sposobów, ale najczęstszą praktyką jest zaimplementowanie przez serwer funkcji „callback” z przekazaniem do niej wymaganego obiektu. Funkcja zwrotna to po prostu funkcja, którą już skonfigurowałeś na kliencie, którą ładowany skrypt wywołuje w momencie ładowania skryptu w celu przetworzenia przekazanych do niego danych.
Przykład:
Mam aplikację, która rejestruje wszystkie pozycje w czyimś domu. Moja aplikacja jest skonfigurowana i chcę teraz pobrać wszystkie przedmioty w głównej sypialni.
Moja aplikacja jest włączona
app.home.com
. Interfejs API, z którego chcę załadować dane, jest włączonyapi.home.com
.O ile serwer nie jest wyraźnie skonfigurowany, aby na to zezwolić, nie mogę użyć Ajax do ładowania tych danych, ponieważ nawet strony w oddzielnych subdomenach podlegają ograniczeniom XHR CORS.
W idealnym przypadku skonfiguruj rzeczy tak, aby umożliwić XHR
W idealnym przypadku, ponieważ interfejs API i aplikacja znajdują się w tej samej domenie, mógłbym mieć dostęp do skonfigurowania nagłówków
api.home.com
. Jeśli tak, mogę dodać elementAccess-Control-Allow-Origin:
nagłówka zapewniający dostęp doapp.home.com
. Zakładając, że nagłówek jest skonfigurowany w następujący sposób:Access-Control-Allow-Origin: "http://app.home.com"
jest to znacznie bezpieczniejsze niż konfiguracja JSONP. Dzieje się tak, ponieważapp.home.com
może uzyskać wszystko, czego chce,api.home.com
bezapi.home.com
zapewniania CORS dostępu do całego Internetu.Powyższe rozwiązanie XHR nie jest możliwe. Skonfiguruj JSONP Na moim skrypcie klienta: Ustawiłem funkcję przetwarzania odpowiedzi z serwera, gdy wykonuję wywołanie JSONP. :
Serwer będzie musiał być tak skonfigurowany, aby zwracał mini skrypt wyglądający jakoś.
"processJSONPResponse('{"room":"main bedroom","items":["bed","chest of drawers"]}');"
Może być przeznaczony do zwracania takiego ciągu, jeśli//api.home.com?getdata=room&room=main_bedroom
zostanie wywołane coś podobnego .Następnie klient konfiguruje tag skryptu jako taki:
To ładuje skrypt i natychmiast wywołuje
window.processJSONPResponse()
jako napisane / echo / wydrukowane przez serwer. Dane przekazane jako parametr do funkcji są teraz przechowywane wdataFromServer
zmiennej lokalnej i możesz z nimi zrobić, co chcesz.Sprzątać
Gdy klient ma już dane tj. natychmiast po dodaniu skryptu do DOM, element skryptu można usunąć z DOM:
źródło
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data
. Po dodaniu pojedynczych cudzysłowów do danych wszystko działało dobrze, więc:"processJSONPResponse('{"room":"main bedroom","items":["bed","chest of drawers"]}');"
Rozumiem, że faktycznie używasz tagów skryptu z JSONP, więc ...
Pierwszym krokiem jest utworzenie funkcji, która będzie obsługiwać JSON:
Upewnij się, że ta funkcja jest dostępna na poziomie globalnym.
Następnie dodaj element skryptu do DOM:
Skrypt załaduje skrypt JavaScript, który tworzy dostawca interfejsu API, i wykona go.
źródło
eval
lubparse
czy czegokolwiek. Powinieneś dostać JavaScript, który przeglądarka może po prostu wykonać, prawda?sposób, w jaki używam jsonp jak poniżej:
następnie użyj metody 'jsonp' w następujący sposób:
odniesienie:
JavaScript XMLHttpRequest przy użyciu JsonP
http://www.w3ctech.com/topic/721 (porozmawiaj o sposobie wykorzystania Promise)
źródło
Mam do tego czystą bibliotekę javascript https://github.com/robertodecurnex/J50Npi/blob/master/J50Npi.js
Przyjrzyj się temu i daj mi znać, jeśli potrzebujesz pomocy w używaniu lub zrozumieniu kodu.
Przy okazji, masz tutaj prosty przykład użycia: http://robertodecurnex.github.com/J50Npi/
źródło
Próbka użycia:
źródło
window[callback] = null
pozwolić funkcji na zbieranie elementów bezużytecznych.Napisałem bibliotekę, aby to załatwić tak prosto, jak to tylko możliwe. Nie ma potrzeby, aby był zewnętrzny, to tylko jedna funkcja. W przeciwieństwie do niektórych innych opcji, ten skrypt czyści się po sobie i jest uogólniony do wysyłania dalszych żądań w czasie wykonywania.
https://github.com/Fresheyeball/micro-jsonp
źródło
Poniżej
JavaScript
przykład wykonaniaJSONP
połączenia bez JQuery:Możesz również polecić moje
GitHub
repozytorium w celach informacyjnych.https://github.com/shedagemayur/JavaScriptCode/tree/master/jsonp
źródło
źródło
window.document.getElementsByTagName('script')[0];
a niedocument.body.appendChild(…)
?logAPI
być ustawione na,null
gdy jest gotowe, aby można było na nim przeprowadzić czyszczenie pamięci?Jeśli używasz ES6 z NPM, możesz wypróbować moduł węzła „fetch-jsonp”. Fetch API Zapewnia obsługę wykonywania wywołań JsonP jako zwykłych wywołań XHR.
Warunek wstępny: powinieneś używać
isomorphic-fetch
modułu node w swoim stosie.źródło
Wklejam tylko wersję ES6 miłej odpowiedzi Sobstela:
źródło