web-dev-qa-db-fra.com

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

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

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 son source contient des données JSON. Comme je l'ai vu, les données ont été téléchargées, comme cela se produit avec les scripts. 

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

La requête JSON à distance après le chargement de la page n'est également pas une option, au cas où vous souhaiteriez le suggérer. 

72
ChuckE

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

Je sais que vous pensez "pourquoi ne puis-je pas simplement utiliser src ici? J'ai déjà vu ce genre de choses ...":

<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>

... bien pour le dire simplement, c’était juste que la balise script était "abusée" en tant que détenteur de données. Vous pouvez le faire avec toutes sortes de données. Par exemple, de nombreux moteurs de gabarit utilisent des balises de script pour contenir des modèles .

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

  1. Utilisez $.get('your.json') ou une autre méthode similaire AJAX.
  2. Ecrivez un fichier qui définit une variable globale sur votre json. (semble hokey).
  3. Tirez-le dans une iframe invisible, puis grattez-en le contenu une fois chargé (j'appelle cela le "mode 1997")
  4. Consultez un prêtre vaudou.

Dernier point: 

La requête JSON à distance après le chargement de la page n'est également pas une option, au cas où vous souhaiteriez le suggérer.

... ça n'a pas de sens. La différence entre une demande AJAX et une demande envoyée par le navigateur lors du traitement de votre <script src=""> est essentiellement nulle. Ils feront tous deux un GET sur la ressource. HTTP ne se soucie pas si cela est fait à cause d'une balise de script ou d'un appel AJAX, et votre serveur ne le fera pas non plus.

94
Ben Lesh

Une autre solution consisterait à utiliser un langage de script côté serveur et à simplement inclure json-data inline. Voici un exemple utilisant 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 de script supplémentaire 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 l'un de l'autre.

8
terabaud

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

A partir de la spécification HTML5 :

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

5
btx9000

Si vous devez charger JSON depuis un autre domaine: http://en.wikipedia.org/wiki/JSONP
Cependant, soyez conscient des attaques potentielles de XSSI: https://www.scip.ch/en/?labs.20160414

Si c'est le même domaine, utilisez simplement Ajax.

2
Vitaliy Kaplich

Cochez cette réponse: https://stackoverflow.com/a/7346598/1764509

$.getJSON("test.json", function(json) {
    console.log(json); // this will show the info it in firebug console
});
2
L.Grillo

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

var mainjson = { your json data}

puis appelez-le depuis la balise script

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

alors vous pouvez l'utiliser dans le prochain script

<script>
console.log(mainjson)
</script>
0
hossein sedighian

Je suis d'accord avec Ben Vous ne pouvez pas charger/importer le fichier JSON simple.

Mais si vous voulez absolument faire cela et avoir la possibilité de mettre à jour le fichier JSON, vous pouvez

my-json.js

   var myJSON = {
      id: "12ws",
      name: "smith"
    }

index.html

<head>
  <script src="my-json.js"></script>
</head>
<body onload="document.getElementById('json-holder').innerHTML = JSON.stringify(myJSON);">
  <div id="json-holder"></div>
</body>
0
Karan

Une autre alternative pour utiliser le json exact dans javascript. Comme il s'agit d'une notation d'objets Javascript, vous pouvez simplement créer votre objet directement avec la notation json. Si vous stockez cela dans un fichier .js, vous pouvez utiliser l'objet dans votre application. C’était une option utile lorsque j’avais des données statiques json que je voulais mettre en cache dans un fichier séparément du reste de mon application.

    //Just hard code json directly within JS
    //here I create an object CLC that represents the json!
    $scope.CLC = {
        "ContentLayouts": [
            {
                "ContentLayoutID": 1,
                "ContentLayoutTitle": "Right",
                "ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/right.png",
                "ContentLayoutIndex": 0,
                "IsDefault": true
            },
            {
                "ContentLayoutID": 2,
                "ContentLayoutTitle": "Bottom",
                "ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/bottom.png",
                "ContentLayoutIndex": 1,
                "IsDefault": false
            },
            {
                "ContentLayoutID": 3,
                "ContentLayoutTitle": "Top",
                "ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/top.png",
                "ContentLayoutIndex": 2,
                "IsDefault": false
            }
        ]
    };
0
DominicTurner