Myślę o osadzeniu dowolnego JSON w DOM w ten sposób:
<script type="application/json" id="stuff">
{
"unicorns": "awesome",
"abc": [1, 2, 3]
}
</script>
Jest to podobne do sposobu, w jaki można przechowywać dowolny szablon HTML w DOM do późniejszego wykorzystania z silnikiem szablonów JavaScript. W takim przypadku moglibyśmy później pobrać JSON i przeanalizować go za pomocą:
var stuff = JSON.parse(document.getElementById('stuff').innerHTML);
To działa , ale czy to najlepszy sposób? Czy narusza to jakiekolwiek najlepsze praktyki lub standardy?
Uwaga: nie szukam alternatywy dla przechowywania JSON w DOM, już zdecydowałem, że to najlepsze rozwiązanie dla konkretnego problemu, który mam. Po prostu szukam najlepszego sposobu, aby to zrobić.
javascript
json
dom
embedding
decoupling
Ben Lee
źródło
źródło
var
w javascript?</script><script>alert()</script><script>
wewnątrz obiektu JSON, otrzymasz niespodzianki. Nie jest to bezpieczne, chyba że najpierw wyczyścisz dane.Odpowiedzi:
Myślę, że twoja oryginalna metoda jest najlepsza. Specyfikacja HTML5 odnosi się nawet do tego użycia:
Przeczytaj tutaj: http://dev.w3.org/html5/spec/Overview.html#the-script-element
Zrobiłeś dokładnie to. Czego nie kochać? Brak wymaganego kodowania znaków z danymi atrybutów. Możesz go sformatować, jeśli chcesz. Jest wyrazisty, a przeznaczenie jest jasne. Nie wygląda to na włamanie (np. Użycie CSS do ukrycia elementu „carrier”). To jest całkowicie poprawne.
źródło
script
tagi.Jako ogólny kierunek, spróbuję zamiast tego użyć atrybutów danych HTML5 . Nic nie stoi na przeszkodzie, aby wprowadzić prawidłowy kod JSON. na przykład:
Jeśli używasz jQuery, odzyskanie go jest tak proste, jak:
źródło
JSON.parse
nie będą działać (przynajmniej natywny Google Chrome JSON.parse nie zadziała). Specyfikacja JSON wymaga podwójnych cudzysłowów. Ale to dość łatwe do naprawienia przy użyciu jednostek takich jak...<unicorns>:...
."I am valid JSON"
użyciem podwójnych cudzysłowów dla tagu lub pojedynczych cudzysłowów z pojedynczymi cudzysłowami w ciągu, np.data-unicorns='"My JSON's string"'
Ponieważ pojedyncze cudzysłowy nie są chronione przed kodowaniem jako JSON.Ta metoda osadzania json w tagu skryptu ma potencjalny problem z bezpieczeństwem. Zakładając, że dane json pochodzą z danych wejściowych użytkownika, możliwe jest utworzenie elementu członkowskiego danych, który w efekcie wyłamie się ze znacznika skryptu i umożliwi bezpośrednie wstrzyknięcie do domeny. Spójrz tutaj:
http://jsfiddle.net/YmhZv/1/
Oto zastrzyk
Po prostu nie ma sposobu na ucieczkę / kodowanie.
źródło
Patrz zasada nr 3.1 w ściągawce OWASP dotyczącej zapobiegania XSS.
Załóżmy, że chcesz dołączyć ten JSON do HTML:
Utwórz ukryty
<div>
w HTML. Następnie wymknij kod JSON, kodując niebezpieczne elementy (np. &, <,>, „, 'I, /) i umieść go wewnątrz elementu.Teraz możesz uzyskać do niego dostęp, czytając
textContent
element za pomocą JavaScript i analizując go:źródło
{name: 'Dwayne "The Rock" Johnson'}
. Ale prawdopodobnie nadal najlepiej jest używać tego podejścia, ponieważ Twoja biblioteka framework / szablonów prawdopodobnie zawiera już bezpieczny sposób kodowania HTML. Alternatywą byłoby użycie base64, który jest zarówno bezpieczny dla HTML, jak i bezpieczny do umieszczenia w ciągu JS. Kodowanie / dekodowanie w JS jest łatwe przy użyciu btoa () / atob () i prawdopodobnie łatwo jest to zrobić po stronie serwera.<data>
elementu i dołączenie danych JSON dovalue
atrybutu. Następnie musisz tylko uciec przed cudzysłowami,"
jeśli używasz podwójnych cudzysłowów do ujęcia danych lub'
jeśli używasz apostrofów (co jest prawdopodobnie lepsze).Sugerowałbym umieszczenie JSON w skrypcie wbudowanym z wywołaniem zwrotnym funkcji (rodzaj JSONP ):
Jeśli skrypt wykonawczy jest ładowany po dokumencie, możesz go gdzieś przechowywać, prawdopodobnie z dodatkowym argumentem identyfikatora:
someCallback("stuff", { ... });
źródło
Moim zaleceniem byłoby przechowywanie danych JSON w
.json
plikach zewnętrznych , a następnie pobieranie tych plików przez Ajax. Nie umieszczasz kodu CSS i JavaScript na stronie internetowej (w tekście), więc dlaczego miałbyś to robić z JSON?źródło
HTML5 zawiera
<data>
element do przechowywania danych do odczytu maszynowego. Jako - być może bezpieczniejsza - alternatywa dla<script type="application/json">
Ciebie, możesz dołączyć dane JSON dovalue
atrybutu tego elementu.W takim przypadku musisz zamienić wszystkie pojedyncze cudzysłowy na
'
lub na,"
jeśli zdecydujesz się ująć wartość w cudzysłów. W przeciwnym razie ryzyko ataków XSS, jak sugerują inne odpowiedzi.źródło