[resolu] Interpréter un JSON via HTTPRequest

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

[resolu] Interpréter un JSON via HTTPRequest

Message par Ar-S »

Salut,

Je suis paumé dans l'utilisation de HTTPRequestMemory pour récupérer les données d'un json générées via un URL

Jusqu'ici je lançais un HTTPRequest

Code : Tout sélectionner

 Request = HTTPRequest(#PB_HTTP_Get, UserUrl$)
 If Request
   If HTTPInfo(Request, #PB_HTTP_StatusCode) = "200"
     HTML$ = HTTPInfo(Request, #PB_HTTP_Response)
     
     Debug HTML$
endif
endif
Le résultat d'HTML$ est bien un contenu de JSON sous cette forme (en une seule ligne)

Code : Tout sélectionner

{
    "Code": 0,
    "message": "OK",
    "data": {
        "champ1": "donnee1",
        "champ2": "donnee2",
        "champ3": "donnee3",
        "champ4": "donnee4"
    }
}
Mais je ne vois pas comment interpréter ce contenue JSON vu que je n'ai pas fait de load/catch JSON
Et comme je ne veux pas écrire sur le disque dur, je me dit qu'il faut que j'utilise HTTPRequestMemory histoire de pouvoir ensuite faire un CatchJson.

Mais la doc n'a pas d'exemple pour HTTPRequestMemory
Resultat = HTTPRequestMemory(Type, URL$ [, *Data, TailleData [, Options [, EnTetes()]]])

.. Je ne vois pas trop comment indiquer TailleData et quoi foutre en EnTetes
Sachant que si j'ai bien compris, c'est le *Data , TailleData qui me serviront dans le catchJson..

Peut être que je me trompe complètement dans mon process mais j'aimerai comprendre.

(pour le moment je parsais le contenu d'HTML$ à coup de findstring/mid etc. ça marche mais c'est dommage de se priver d'une fonction existante.)

Merci de m'éclairer.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Naheulf
Messages : 191
Inscription : dim. 10/mars/2013 22:22
Localisation : France

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Naheulf »

Si j'ai bien compris, HTTPRequestMemory() c'est lorsque tu veut faire des requêtes de type "POST" et que les données à envoyer sont dans la mémoire.

On a (si j'ai bien compris) :
  • *data : pointeur vers les données à envoyer
  • tailleData : taille brute des données à envoyer
Aux options près, et si je ne me plante pas sur le fonctionnement du protocole HTTP, on a donc :

Code : Tout sélectionner

HTTPRequestMemory(Type, URL$ [, *Data, TailleData [, OptionsHTTP [, EnTetes()]]])
qui équivaut à faire

Code : Tout sélectionner

HTTPRequest(Type, URL$ [, Base64Encoder(*Data, TailleData [, Options64]) [, OptionsHTTP [, EnTetes()]]])
Édit : Le Base64 ne servant que pour transmettre les données binaires susceptible de contenir des codes pouvant interférer avec la bonne gestion/transmission de la requête.
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Marc56 »

Je comprends peut-être (encore) de travers, mais si ce que tu veux faire est ne pas écrire de fichier sur le disque dur, il n'y a pas de problème car le contenu retour de HTTPRequest se fait dans une variable chaine de caractères.
Après tu peux extraire les données avec les fonctions JSON ou les fonction texte.

Code : Tout sélectionner

InitNetwork()

UserUrl$ = "http://127.0.0.1/Test_Ar-S.php"

Request = HTTPRequest(#PB_HTTP_Get, UserUrl$)
If Request
    If HTTPInfo(Request, #PB_HTTP_StatusCode) = "200"
        HTML$ = HTTPInfo(Request, #PB_HTTP_Response)
        
        Debug HTML$
    EndIf
EndIf

For i = 1 To CountString(HTML$, #CRLF$)
    Debug "Ligne #" + i + " " + StringField(HTML$, i, #CRLF$)
Next

Code : Tout sélectionner

{
    "Code": 0,
    "message": "OK",
    "data": {
        "champ1": "donnee1",
        "champ2": "donnee2",
        "champ3": "donnee3",
        "champ4": "donnee4",
    }
}
Ligne #1 {
Ligne #2     "Code": 0,
Ligne #3     "message": "OK",
Ligne #4     "data": {
Ligne #5         "champ1": "donnee1",
Ligne #6         "champ2": "donnee2",
Ligne #7         "champ3": "donnee3",
Ligne #8         "champ4": "donnee4",
Ligne #9     }
Différence entre les deux fonctions (dixit l'aide)
HTTPRequest Envoie une requête HTTP avec des données textuelles optionnelles.
HTTPRequestMemory Envoie une requête HTTP avec des données binaires optionnelles.

Quant à la différence entre POST et GET. Principales différences et usages:
- GET envoie les données dans l'URL (donc utile pour bookmarker, mais laisse les données envoyée visibles)
- POST envoie les données dans le corps du message (données invisibles aux intermédiaires (ie: proxy)) mais on ne peut pas bookmarker car les données n'existent que lors de l'envoi.

Pour plus de détails c'est mieux expliqué ici que dans les textes en français
https://www.w3schools.com/tags/ref_httpmethods.asp

:wink:
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Ar-S »

HTTPRequestMemory() c'est lorsque tu veux faire des requêtes de type "POST"
Ahlàlà j'ai occulté le POST...

Une chose est sûr, je n'aime pas du tout la syntaxe Json et encore moins leurs traitements, mais alors pas du tout...
En attendant une réponse j'ai utilisé des stringfield (à la place de mes vieux findstring) et j'ai solutionné mon soucis.

Code : Tout sélectionner

truc$ = RemoveString (StringField(HTML$, 4, ",") , "champ1:") pour obtenir "donnees1"
Merci pour tes éclaircissements, on arrive à la même conclusion pour le traitement ce qui me rassure.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
case
Messages : 1528
Inscription : lun. 10/sept./2007 11:13

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par case »

ça ne marchera que si tes données par exemple des chaines de caractères ne contiennent pas de virgule.
sinon ton stringfield vas couper ta donnée en deux et cela décalera tout le reste.
:mrgreen:
ImageImage
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Ar-S »

Les données que je récup sont toujours formatés de la même manière. Pas de risque. (sinon j'aurai fait plus de vérif ;))
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Marc56 »

Juste pour le côté fun, la version regex pour extraire l'objet même s'il y a une virgule dedans.
Pour extraire un autre objet, changes "champ1" dans la regex

Note: Test_A.php est un simple fichier texte contenant ton JSON (corrigé de la virgule en trop qui le met en erreur "donnee4",). Ce fichier est sur un serveur web local (Apache + PHP)

Code : Tout sélectionner

InitNetwork()

UserUrl$ = "http://127.0.0.1/Test_A.php"

Request = HTTPRequest(#PB_HTTP_Get, UserUrl$)
If Request
    If HTTPInfo(Request, #PB_HTTP_StatusCode) = "200"
        HTML$ = HTTPInfo(Request, #PB_HTTP_Response)
    EndIf
EndIf

If CreateRegularExpression(0, 
                           ~"\"data\".+\"champ1\".+?\"(.+?)\"", 
                           #PB_RegularExpression_DotAll)
    
    If ExamineRegularExpression(0, HTML$)
        While NextRegularExpressionMatch(0)
            Debug RegularExpressionGroup(0, 1)
        Wend    
    EndIf
    
    FreeRegularExpression(0)
Else
    Debug RegularExpressionError()
EndIf

End
PS. Il faut tester les erreurs JSON après un Parse... car sinon, le système n'affiche rien et on pense à une données absente.

Code : Tout sélectionner

If ParseJSON(0, HTML$, #PB_JSON_NoCase)
   ...
Else
    Debug "Erreur   : " + JSONErrorMessage()
    Debug "Ligne    : " + JSONErrorLine()
    Debug "Position : " + JSONErrorPosition()
    End
EndIf
(Je n'aime pas non plus le format JSON et ses fonctions de gestion)
:wink:
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Ar-S »

J'ai effectivement mis une virgule de trop dans mon exemple. Merci de l'avoir signalé. C'est corrigé.
Merci pour cet exemple de regex. J'y ai pensé quand le json me pompait, mais vu le format fixe des requêtes et des retours, le stringfield reste mon choix de prédilection.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par falsam »

Je déterre ce sujet suite à une conversation avec Ar-s aujourd'hui sur le serveur Discord de PureBasic.

Ar-s cherche à récupérer des données HTTP au format JSON dans une structure PB.

n'ayant pas le lien pour downloader les données, j'ai mis un exemple des données dans un fichier texte.

Code : Tout sélectionner

{
   "statusCode":0,
   "message":"Success",
   "data":{
      "list":[
         {
            "file_code":"cb3137715",
            "file_name":"nomfichier.ext",
            "file_size":23351305,
            "available_uts":true,
            "need_premium":false,
            "subtitles":[
               {
                  "type":"vtt",
                  "src":"https://www34.url/suite.vtt",
                  "label":"Forced",
                  "srcLang":"fre"
               },
               {
                  "type":"vtt",
                  "src":"https://www34.url/suite.vtt",
                  "label":"French",
                  "srcLang":"fre"
               }
            ]
         }
      ]
   }
}
Décryptage du JSON.

- "statusCode" -> Integer
- "message" -> String
-- "data" -> Object
--- "list" -> Array
---- "subtitles" -> Array

Code.

Code : Tout sélectionner

EnableExplicit

Structure Def_SubTitles
  type.s
  src.s
  label.s
  srcLang.s
EndStructure

Structure Def_List
  file_code.s 
  file_name.s 
  file_size.i 
  available_uts.b
  need_premium.b
  Array subtitles.Def_SubTitles(0)
EndStructure

Structure Def_Data
  Array List.Def_List(0)
EndStructure 

Structure NewRecord 
  statusCode.i
  message.s
  Data.Def_Data
EndStructure

Define Record.Newrecord

; Chargement du fichier
Define Result = LoadJSON(#PB_Any, "test.json", #PB_JSON_NoCase )

; Chargement dans la structure associée
ExtractJSONStructure(JSONValue(Result), Record, NewRecord)

; Vérification de l'intégrité du JSON
Debug ComposeJSON(Result, #PB_JSON_PrettyPrint)
Debug #CRLF$

; Debug 
Debug "Debug de quelques items"

Debug Record\statusCode
Debug Record\message
Debug Record\Data\List(0)\file_name
Debug Record\Data\List(0)\subtitles(0)\src
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par falsam »

Il est possible de ne pas définir l'intégralité des données reçues.

Code : Tout sélectionner

EnableExplicit

Structure Def_List
  file_code.s 
  file_name.s 
EndStructure

Structure Def_Data
  Array List.Def_List(0)
EndStructure 

Structure NewRecord 
  Data.Def_Data
EndStructure

Define Record.Newrecord

; Chargement du fichier
Define Result = LoadJSON(#PB_Any, "test.json", #PB_JSON_NoCase )

; Chargement dans la structure associée
ExtractJSONStructure(JSONValue(Result), Record, NewRecord)

; Debug 
Debug "Debug de quelques items"

Debug Record\Data\List(0)\file_code
Debug Record\Data\List(0)\file_name
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Comment récupérer un JSON via HTTPRequestMemory

Message par Ar-S »

Merci Falsam. Avec le code de Naheulf et le tiens je vais tâcher de piger le fonctionnement.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Répondre