Pregunta

Necesito hacer una solicitud HTTP GET en JavaScript. ¿Cuál es la mejor manera de hacerlo?

Necesito hacer esto en un widget de código de tablero de Mac OS X.

¿Fue útil?

Solución

Los navegadores (y Dashcode) proporcionan un objeto XMLHttpRequest que se puede usar para realizar solicitudes HTTP desde JavaScript:

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

Sin embargo, se desaconsejan las solicitudes sincrónicas y generarán una advertencia en la línea de:

  

Nota: Comenzando con Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), las solicitudes síncronas en el hilo principal han quedado en desuso debido a los efectos negativos para la experiencia del usuario.

Debe realizar una solicitud asincrónica y manejar la respuesta dentro de un controlador de eventos.

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);
}

Otros consejos

En jQuery :

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

Muchos consejos excelentes arriba, pero no muy reutilizables, y muy a menudo llenos de tonterías DOM y otras pelusas que ocultan el código fácil.

Aquí hay una clase de Javascript que creamos que es reutilizable y fácil de usar. Actualmente solo tiene un método GET, pero eso funciona para nosotros. Agregar una POST no debería gravar las habilidades de nadie.

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 );
    }
}

Su uso es tan fácil como:

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

Una versión sin devolución de llamada

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

El nuevo window.fetch API es un reemplazo más limpio para XMLHttpRequest que hace uso de las promesas de ES6. Hay una buena explicación aquí , pero se reduce a (del artículo):

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

El soporte del navegador ahora es bueno en las últimas versiones (funciona en Chrome, Firefox, Edge (v14 ), Safari (v10.1), Opera, Safari iOS (v10.3), navegador de Android y Chrome para Android), sin embargo, es probable que IE no obtenga soporte oficial. GitHub tiene un polyfill disponible que se recomienda para admitir navegadores más antiguos aún en uso (especialmente las versiones de Safari antes de marzo 2017 y navegadores móviles del mismo período).

Supongo que si esto es más conveniente que jQuery o XMLHttpRequest o no depende de la naturaleza del proyecto.

Aquí hay un enlace a la especificación https://fetch.spec.whatwg.org/

Editar :

Usando ES7 async / await, esto se convierte simplemente en (basado en this Gist ):

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

Aquí hay un código para hacerlo directamente con JavaScript. Pero, como se mencionó anteriormente, estarías mucho mejor con una biblioteca de JavaScript. Mi favorito es jQuery.

En el caso a continuación, se llama a una página ASPX (que funciona como el servicio REST de un hombre pobre) para devolver un objeto JSON de 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;
        }                    
    }
}

Una versión lista para copiar y pegar

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 almacenará en caché las URL para que la carga sea más rápida, pero si, por ejemplo, está encuestando un servidor a intervalos tratando de obtener nueva información, IE almacenará en caché esa URL y probablemente devolverá el mismo conjunto de datos que siempre ha tenido.

Independientemente de cómo termine haciendo su solicitud GET (JavaScript vainilla, Prototype, jQuery, etc.) asegúrese de establecer un mecanismo para combatir el almacenamiento en caché. Para combatir eso, agrega un token único al final de la URL que vas a utilizar. Esto se puede hacer:

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

Esto agregará una marca de tiempo única al final de la URL y evitará que ocurra cualquier almacenamiento en caché.

Corto y puro:

const http = new XMLHttpRequest()

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

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

Prototype lo hace muy simple

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

No estoy familiarizado con los Widgets de Dashcode de Mac OS, pero si te permiten usar bibliotecas de JavaScript y es compatible con XMLHttpRequests , usaría jQuery y haría algo como esto :

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

Una solución compatible con navegadores antiguos:

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);
            }
        }
    };
}

Tal vez sea un poco exagerado, pero definitivamente vas a salvo con este código.

Uso:

//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();

En el archivo Info.plist de tu widget, no olvides establecer tu clave AllowNetworkAccess en true.

La mejor manera es usar AJAX (puede encontrar un tutorial sencillo en esta página Tizag ). La razón es que cualquier otra técnica que pueda usar requiere más código, no se garantiza que funcione en varios navegadores sin volver a trabajar y requiere que use más memoria del cliente abriendo páginas ocultas dentro de marcos pasando URLs analizando sus datos y cerrándolos. AJAX es el camino a seguir en esta situación. Que mis dos años de desarrollo pesado javascript hablando.

Para aquellos que usan AngularJs , es $ 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.
  });

Puedes obtener una solicitud HTTP GET de dos formas:

  1. Este enfoque basado en formato xml. Tienes que pasar la URL para la solicitud.

    xmlhttp.open("GET","URL",true);
    xmlhttp.send();
    
  2. Este se basa en jQuery. Debe especificar la URL y el nombre de función al que desea llamar.

    $("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/')

También se puede hacer lo mismo para la solicitud posterior.
Eche un vistazo a este enlace Solicitud de publicación de JavaScript como un formulario enviado

Para hacer esto, Fetch API es el enfoque recomendado, usando Promesas de JavaScript. XMLHttpRequest (XHR), el objeto IFrame o las etiquetas dinámicas son enfoques más antiguos (y más complicados).

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

Aquí hay un gran fetch demo y MDN docs

Solicitud asíncrona 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

Sería mejor usar una biblioteca como Prototype o jQuery .

Si desea utilizar el código para un widget de Panel de control y no desea incluir una biblioteca de JavaScript en cada widget que haya creado, puede utilizar el objeto XMLHttpRequest que Safari admite de forma nativa.

Como informó Andrew Hedges, un widget no tiene acceso a una red, por defecto; debe cambiar esa configuración en la lista de información asociada con el widget.

Para actualizar la mejor respuesta de joann con la promesa, este es mi código:

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();
    });
}

También puedes hacerlo con JS puro:

// 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();
}

Consulte: para obtener más detalles: tutorial html5rocks

Aquí hay una alternativa a los archivos xml para cargar tus archivos como un objeto y acceder a las propiedades como un objeto de una manera muy rápida.

  • Atención, para que javascript lo pueda e interpretar el contenido correctamente, es necesario guardar sus archivos en el mismo formato que su página HTML. Si usa UTF 8, guarde sus archivos en UTF8, etc.

XML funciona como un árbol ok? en lugar de escribir

     <property> value <property> 

escriba un archivo simple como este:

      Property1: value
      Property2: value
      etc.

Guarde su archivo ... Ahora llama a la función ....

    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();
}

ahora puede obtener sus valores de manera eficiente.

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

window.onload = function(){

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

Es solo un pequeño regalo para contribuir al grupo. Gracias de tu me gusta :)

Si desea probar la función en su PC localmente, reinicie su navegador con el siguiente comando (compatible con todos los navegadores excepto safari):

yournavigator.exe '' --allow-file-access-from-files
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top