Question

Je dois effectuer une demande HTTP GET en JavaScript. Quelle est la meilleure façon de faire cela?

Je dois le faire dans un widget de dashcode Mac OS X.

Était-ce utile?

La solution

Les navigateurs (et Dashcode) fournissent un objet XMLHttpRequest qui peut être utilisé pour effectuer des requêtes HTTP à partir de JavaScript:

function httpGet(theUrl)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
    xmlHttp.send( null );
    return xmlHttp.responseText;
}

Toutefois, les requêtes synchrones sont déconseillées et généreront un avertissement du type:

  

Remarque: à partir de Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), les demandes synchrones sur le thread principal sont déconseillées en raison des effets négatifs sur l'expérience utilisateur.

Vous devez faire une requête asynchrone et gérer la réponse dans un gestionnaire d'événements.

function httpGetAsync(theUrl, callback)
{
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.onreadystatechange = function() { 
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            callback(xmlHttp.responseText);
    }
    xmlHttp.open("GET", theUrl, true); // true for asynchronous 
    xmlHttp.send(null);
}

Autres conseils

Dans jQuery :

$.get(
    "somepage.php",
    {paramOne : 1, paramX : 'abc'},
    function(data) {
       alert('page content: ' + data);
    }
);

Beaucoup de bons conseils ci-dessus, mais pas très réutilisables, et trop souvent remplis de bêtises DOM et d’autres peluches qui cachent le code facile.

Nous avons créé une classe Javascript réutilisable et facile à utiliser. Actuellement, il ne dispose que d'une méthode GET, mais cela fonctionne pour nous. Ajouter un POST ne devrait pas taxer les compétences de quiconque.

var HttpClient = function() {
    this.get = function(aUrl, aCallback) {
        var anHttpRequest = new XMLHttpRequest();
        anHttpRequest.onreadystatechange = function() { 
            if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
                aCallback(anHttpRequest.responseText);
        }

        anHttpRequest.open( "GET", aUrl, true );            
        anHttpRequest.send( null );
    }
}

L’utiliser est aussi simple que:

var client = new HttpClient();
client.get('http://some/thing?with=arguments', function(response) {
    // do something with response
});

Une version sans rappel

var i = document.createElement("img");
i.src = "/your/GET/url?params=here";

Le nouveau window.fetch L'API est un remplacement plus propre de XMLHttpRequest qui utilise les promesses ES6. Il existe une bonne explication ici , mais cela revient à (à partir de l'article):

fetch(url).then(function(response) {
  return response.json();
}).then(function(data) {
  console.log(data);
}).catch(function() {
  console.log("Booo");
});
La

prise en charge du navigateur est désormais opérationnelle dans les dernières versions (fonctionne dans Chrome, Firefox, Edge (v14). ), Safari (v10.1), Opera, Safari iOS (v10.3), navigateur Android et Chrome pour Android), mais IE n’obtiendra probablement pas de support officiel. GitHub dispose d'un polyfill qui est recommandé pour prendre en charge les anciens navigateurs encore largement utilisés (notamment les versions de Safari antérieures à mars). 2017 et les navigateurs mobiles de la même période).

Je suppose que cela est plus pratique que jQuery ou XMLHttpRequest ou non dépend de la nature du projet.

Voici un lien vers la spécification https://fetch.spec.whatwg.org/

Modifier :

En utilisant ES7 async / wait, cela devient simplement (selon ce Gist ):

async function fetchAsync (url) {
  let response = await fetch(url);
  let data = await response.json();
  return data;
}

Voici le code pour le faire directement avec JavaScript. Mais, comme mentionné précédemment, vous seriez beaucoup mieux avec une bibliothèque JavaScript. Mon préféré est jQuery.

Dans le cas ci-dessous, une page ASPX (appelée service REST d'un homme pauvre) est appelée pour renvoyer un objet JSON JavaScript.

var xmlHttp = null;

function GetCustomerInfo()
{
    var CustomerNumber = document.getElementById( "TextBoxCustomerNumber" ).value;
    var Url = "GetCustomerInfoAsJson.aspx?number=" + CustomerNumber;

    xmlHttp = new XMLHttpRequest(); 
    xmlHttp.onreadystatechange = ProcessRequest;
    xmlHttp.open( "GET", Url, true );
    xmlHttp.send( null );
}

function ProcessRequest() 
{
    if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 ) 
    {
        if ( xmlHttp.responseText == "Not found" ) 
        {
            document.getElementById( "TextBoxCustomerName"    ).value = "Not found";
            document.getElementById( "TextBoxCustomerAddress" ).value = "";
        }
        else
        {
            var info = eval ( "(" + xmlHttp.responseText + ")" );

            // No parsing necessary with JSON!        
            document.getElementById( "TextBoxCustomerName"    ).value = info.jsonData[ 0 ].cmname;
            document.getElementById( "TextBoxCustomerAddress" ).value = info.jsonData[ 0 ].cmaddr1;
        }                    
    }
}

Une version prête à copier-coller

let request = new XMLHttpRequest();
request.onreadystatechange = function () {
    if (this.readyState === 4) {
        if (this.status === 200) {
            document.body.className = 'ok';
            console.log(this.responseText);
        } else if (this.response == null && this.status === 0) {
            document.body.className = 'error offline';
            console.log("The computer appears to be offline.");
        } else {
            document.body.className = 'error';
        }
    }
};
request.open("GET", url, true);
request.send(null);

IE mettra en cache les URL pour accélérer le chargement, mais si, par exemple, vous interrogez un serveur à intervalles réguliers pour obtenir de nouvelles informations, IE met en cache cette URL et renverra probablement le même ensemble de données que celui que vous avez toujours utilisé. avait.

Quel que soit le type de demande GET que vous utilisez (JavaScript vanille, Prototype, jQuery, etc.), veillez à mettre en place un mécanisme permettant de lutter contre la mise en cache. Afin de lutter contre cela, ajoutez un jeton unique à la fin de l'URL que vous allez frapper. Cela peut être fait par:

var sURL = '/your/url.html?' + (new Date()).getTime();

Ceci ajoutera un horodatage unique à la fin de l'URL et empêchera toute mise en cache.

Court et pur:

const http = new XMLHttpRequest()

http.open("GET", "https://api.lyrics.ovh/v1/toto/africa")
http.send()

http.onload = () => console.log(http.responseText)

Le prototype simplifie les choses

new Ajax.Request( '/myurl', {
  method:  'get',
  parameters:  { 'param1': 'value1'},
  onSuccess:  function(response){
    alert(response.responseText);
  },
  onFailure:  function(){
    alert('ERROR');
  }
});

Je ne connais pas bien les widgets Dashcode de Mac OS, mais s’ils vous permettent d’utiliser les bibliothèques JavaScript et de prendre en charge XMLHttpRequests , j'utiliserais jQuery et ferais quelque chose de similaire :

var page_content;
$.get( "somepage.php", function(data){
    page_content = data;
});

Une solution prenant en charge les anciens navigateurs:

function httpRequest() {
    var ajax = null,
        response = null,
        self = this;

    this.method = null;
    this.url = null;
    this.async = true;
    this.data = null;

    this.send = function() {
        ajax.open(this.method, this.url, this.asnyc);
        ajax.send(this.data);
    };

    if(window.XMLHttpRequest) {
        ajax = new XMLHttpRequest();
    }
    else if(window.ActiveXObject) {
        try {
            ajax = new ActiveXObject("Msxml2.XMLHTTP.6.0");
        }
        catch(e) {
            try {
                ajax = new ActiveXObject("Msxml2.XMLHTTP.3.0");
            }
            catch(error) {
                self.fail("not supported");
            }
        }
    }

    if(ajax == null) {
        return false;
    }

    ajax.onreadystatechange = function() {
        if(this.readyState == 4) {
            if(this.status == 200) {
                self.success(this.responseText);
            }
            else {
                self.fail(this.status + " - " + this.statusText);
            }
        }
    };
}

Peut-être un peu exagéré, mais vous êtes définitivement en sécurité avec ce code.

Utilisation:

//create request with its porperties
var request = new httpRequest();
request.method = "GET";
request.url = "https://example.com/api?parameter=value";

//create callback for success containing the response
request.success = function(response) {
    console.log(response);
};

//and a fail callback containing the error
request.fail = function(error) {
    console.log(error);
};

//and finally send it away
request.send();

Dans le fichier Info.plist de votre widget, n'oubliez pas de définir la clé AllowNetworkAccess sur true.

Le meilleur moyen est d’utiliser AJAX (vous trouverez un tutoriel simple sur cette page Tizag ). La raison en est que toute autre technique que vous utilisez nécessite plus de code, il n’est pas garanti qu’il fonctionne avec tous les navigateurs sans retravailler et nécessite que vous utilisiez plus de mémoire client en ouvrant des pages cachées à l’intérieur de cadres qui passaient des URL analysant et fermant leurs données. AJAX est la voie à suivre dans cette situation. Que mes deux années de développement javascript lourd parlent.

Pour ceux qui utilisent AngularJs , il s’agit de $ http .get :

$http.get('/someUrl').
  success(function(data, status, headers, config) {
    // this callback will be called asynchronously
    // when the response is available
  }).
  error(function(data, status, headers, config) {
    // called asynchronously if an error occurs
    // or server returns response with an error status.
  });

Vous pouvez obtenir une demande HTTP GET de deux manières:

  1. Cette approche est basée sur le format XML. Vous devez transmettre l'URL de la demande.

    xmlhttp.open("GET","URL",true);
    xmlhttp.send();
    
  2. Celui-ci est basé sur jQuery. Vous devez spécifier l'URL et le nom_fonction que vous souhaitez appeler.

    $("btn").click(function() {
      $.ajax({url: "demo_test.txt", success: function_name(result) {
        $("#innerdiv").html(result);
      }});
    }); 
    
function get(path) {
    var form = document.createElement("form");
    form.setAttribute("method", "get");
    form.setAttribute("action", path);
    document.body.appendChild(form);
    form.submit();
}


get('/my/url/')

La même chose peut être faite pour une demande de publication.
Consultez ce lien une demande de publication JavaScript comme un formulaire à envoyer

Pour ce faire, l'API de récupération est l'approche recommandée, à l'aide de promesses JavaScript. XMLHttpRequest (XHR), un objet IFrame ou des balises dynamiques sont des approches plus anciennes (et plus encombrantes).

<script type=“text/javascript”> 
    // Create request object 
    var request = new Request('https://example.com/api/...', 
         { method: 'POST', 
           body: {'name': 'Klaus'}, 
           headers: new Headers({ 'Content-Type': 'application/json' }) 
         });
    // Now use it! 

   fetch(request) 
   .then(resp => { 
         // handle response }) 
   .catch(err => { 
         // handle errors 
    }); </script>

Voici un excellent chercher démo et Documents MDN

Requête async simple:

function get(url, callback) {
  var getRequest = new XMLHttpRequest();

  getRequest.open("get", url, true);

  getRequest.addEventListener("readystatechange", function() {
    if (getRequest.readyState === 4 && getRequest.status === 200) {
      callback(getRequest.responseText);
    }
  });

  getRequest.send();
}

Ajax

Vous feriez mieux d'utiliser une bibliothèque telle que Prototype ou jQuery .

Si vous souhaitez utiliser le code d'un widget Dashboard et que vous ne souhaitez pas inclure une bibliothèque JavaScript dans chaque widget que vous avez créé, vous pouvez utiliser l'objet XMLHttpRequest que Safari prend en charge de manière native.

Comme l'a signalé Andrew Hedges, un widget n'a pas accès à un réseau, par défaut; vous devez modifier ce paramètre dans le fichier info.plist associé au widget.

Pour actualiser la meilleure réponse de joann avec la promesse que ceci est mon code:

let httpRequestAsync = (method, url) => {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open(method, url);
        xhr.onload = function () {
            if (xhr.status == 200) {
                resolve(xhr.responseText);
            }
            else {
                reject(new Error(xhr.responseText));
            }
        };
        xhr.send();
    });
}

Vous pouvez aussi le faire avec du JS pur:

// Create the XHR object.
function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}

// Make the actual CORS request.
function makeCorsRequest() {
 // This is a sample server that supports CORS.
 var url = 'http://html5rocks-cors.s3-website-us-east-1.amazonaws.com/index.html';

var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}

// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
alert('Response from CORS request to ' + url + ': ' + text);
};

xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};

xhr.send();
}

Voir: pour plus de détails: didacticiel html5rocks

Voici une alternative aux fichiers xml pour charger vos fichiers en tant qu'objet et accéder aux propriétés en tant qu'objet de manière très rapide.

  • Attention, pour que javascript le puisse et pour interpréter correctement le contenu il est nécessaire de sauvegarder vos fichiers au même format que votre page HTML. Si vous utilisez UTF 8, enregistrez vos fichiers au format UTF8, etc.

XML fonctionne comme un arbre ok? au lieu d'écrire

     <property> value <property> 

écrivez un fichier simple comme celui-ci:

      Property1: value
      Property2: value
      etc.

Enregistrez votre fichier. Appelez maintenant la fonction ....

    var objectfile = {};

function getfilecontent(url){
    var cli = new XMLHttpRequest();

    cli.onload = function(){
         if((this.status == 200 || this.status == 0) && this.responseText != null) {
        var r = this.responseText;
        var b=(r.indexOf('\n')?'\n':r.indexOf('\r')?'\r':'');
        if(b.length){
        if(b=='\n'){var j=r.toString().replace(/\r/gi,'');}else{var j=r.toString().replace(/\n/gi,'');}
        r=j.split(b);
        r=r.filter(function(val){if( val == '' || val == NaN || val == undefined || val == null ){return false;}return true;});
        r = r.map(f => f.trim());
        }
        if(r.length > 0){
            for(var i=0; i<r.length; i++){
                var m = r[i].split(':');
                if(m.length>1){
                        var mname = m[0];
                        var n = m.shift();
                        var ivalue = m.join(':');
                        objectfile[mname]=ivalue;
                }
            }
        }
        }
    }
cli.open("GET", url);
cli.send();
}

Maintenant, vous pouvez obtenir vos valeurs efficacement.

getfilecontent('mesite.com/mefile.txt');

window.onload = function(){

if(objectfile !== null){
alert (objectfile.property1.value);
}
}

C’est juste un petit cadeau à faire au groupe. Merci de votre pareil:)

Si vous souhaitez tester la fonction sur votre PC localement, redémarrez votre navigateur avec la commande suivante (prise en charge par tous les navigateurs sauf Safari):

yournavigator.exe '' --allow-file-access-from-files
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top