121 votes

HTML/Javascript : comment accéder aux données JSON chargées dans une balise script avec src set

J'ai ce fichier JSON que je génère sur le serveur et que je veux rendre accessible sur le client comme la page est visualisable. En gros, ce que je veux réaliser est le suivant :

J'ai la balise suivante déclarée dans mon document html :

<script id="test" type="application/json" src="http://myresources/stuf.json">

Le fichier référencé dans sa source contient des données JSON. Comme je l'ai vu, les données ont été téléchargées, tout comme cela se passe avec les scripts.

Maintenant, comment puis-je y accéder en Javascript ? J'ai essayé d'accéder à la balise script, avec et sans jQuery, en utilisant une multitude de méthodes pour essayer d'obtenir mes données JSON, mais d'une manière ou d'une autre, cela ne fonctionne pas. Obtenir son innerHTML aurait fonctionné si les données json avaient été écrites en ligne dans le script. Ce qui n'a pas été le cas et ce n'est pas ce que j'essaie de faire.

La demande JSON à distance après le chargement de la page n'est pas non plus une option, au cas où vous voudriez la suggérer.

133voto

Ben Lesh Points 39290

Vous ne pouvez pas charger JSON comme ça, désolé.

Je sais que vous pensez "pourquoi je ne peux pas juste utiliser src ici ? J'ai déjà vu des trucs comme ça..." :

<script id="myJson" type="application/json">
 { 
   name: 'Foo' 
 }
</script>

<script type="text/javascript">
    $(function() {
        var x = JSON.parse($('#myJson').html());
        alert(x.name); //Foo
     });
</script>

... et bien pour le dire simplement, c'était juste la balise script qui était "abusée" comme support de données. Vous pouvez faire cela avec toutes sortes de données. Par exemple, beaucoup de moteurs de modèles utilisent les balises script pour contenir les modèles. .

Vous disposez d'une courte liste d'options pour charger votre JSON à partir d'un fichier distant :

  1. Utilice $.get('your.json') ou une autre méthode AJAX de ce type.
  2. Écrire un fichier qui définit une variable globale à votre json. (semble hokey).
  3. Le placer dans une iframe invisible, puis en extraire le contenu une fois qu'elle est chargée (j'appelle cela le "mode 1997").
  4. Consultez un prêtre vaudou.

Dernier point :

La demande JSON à distance après le chargement de la page n'est pas non plus une option, au cas où vous voudriez la suggérer.

... qui n'a pas de sens. La différence entre une requête AJAX et une requête envoyée par le navigateur lors du traitement de votre site Web. <script src=""> n'est essentiellement rien. Ils feront tous les deux un GET sur la ressource. HTTP ne se soucie pas de savoir si c'est fait à cause d'une balise script ou d'un appel AJAX, et votre serveur non plus.

21voto

terabaud Points 517

Une autre solution serait d'utiliser un langage de script côté serveur et d'inclure simplement les données json en ligne. Voici un exemple qui utilise PHP :

<script id="data" type="application/json"><?php include('stuff.json'); ?></script>
<script>
var jsonData = JSON.parse(document.getElementById('data').textContent)
</script>

L'exemple ci-dessus utilise une balise supplémentaire script de type application/json . Une solution encore plus simple consiste à inclure le JSON directement dans le JavaScript :

<script>var jsonData = <?php include('stuff.json');?>;</script>

L'avantage de la solution avec la balise supplémentaire est que le code JavaScript et les données JSON sont séparés les uns des autres.

13voto

btx9000 Points 69

Il semblerait que cela ne soit pas possible, ou du moins pas pris en charge.

De la Spécification HTML5 :

Lorsqu'il est utilisé pour inclure blocs de données (par opposition à scripts), les données doivent être incorporées en ligne le format des données doit être indiqué à l'aide de l'attribut type, l'attribut src ne doit pas être spécifié et le contenu de l'élément script doit être conforme aux exigences définies pour le format utilisé.

8voto

Grimbode Points 690

Bien que ce ne soit pas possible actuellement avec le script il est possible avec une balise iframe s'il s'agit du même domaine.

<iframe
id="mySpecialId"
src="/my/link/to/some.json"
onload="(()=>{if(!window.jsonData){window.jsonData={}}try{window.jsonData[this.id]=JSON.parse(this.contentWindow.document.body.textContent.trim())}catch(e){console.warn(e)}this.remove();})();"
onerror="((err)=>console.warn(err))();"
style="display: none;"
></iframe>

Pour utiliser ce qui précède, il suffit de remplacer le id y src attribut avec ce dont vous avez besoin. Le site id (que nous supposerons dans cette situation être égale à mySpecialId ) sera utilisé pour stocker le données en window.jsonData["mySpecialId"] .

En d'autres termes, pour chaque iframe qui a une id et utilise le onload script aura ces données. de manière synchrone chargé dans le window.jsonData sous le id spécifié.

J'ai fait ça pour m'amuser et pour montrer que c'est "possible", mais je ne pas recommande de l'utiliser.


Voici une alternative qui utilise un callback à la place.

<script>
    function someCallback(data){
        /** do something with data */
        console.log(data);

    }
    function jsonOnLoad(callback){
        const raw = this.contentWindow.document.body.textContent.trim();
        try {
          const data = JSON.parse(raw);
          /** do something with data */
          callback(data);
        }catch(e){
          console.warn(e.message);
        }
        this.remove();
    }
</script>
<!-- I frame with src pointing to json file on server, onload we apply "this" to have the iframe context, display none as we don't want to show the iframe -->
<iframe src="your/link/to/some.json" onload="jsonOnLoad.apply(this, someCallback)" style="display: none;"></iframe>

Testé dans chrome et devrait fonctionner dans firefox. Je ne suis pas sûr pour IE ou Safari.

7voto

hossein sedighian Points 987

Placez quelque chose comme ceci dans votre fichier script. json-content.js

var mainjson = { your json data}

puis l'appeler à partir de la balise script.

<script src="json-content.js"></script>

alors vous pouvez l'utiliser dans le prochain script.

<script>
console.log(mainjson)
</script>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X