¿Cómo llamar a una API de servicio web REST desde JavaScript?

166

Tengo una página HTML con un botón. Cuando hago clic en ese botón, necesito llamar a una API de servicio web REST. Intenté buscar en línea en todas partes. No tengo idea alguna. ¿Alguien puede darme una pista / Headstart sobre esto? Muy apreciado.

Shaik Syed Ali
fuente
Su llamada al servicio REST es solo una solicitud al servidor, supongo que será una solicitud ajax. Use jQuery por ejemplo api.jquery.com/jquery.ajax
ikos23

Respuestas:

174

Me sorprende que nadie haya mencionado la nueva API Fetch, compatible con todos los navegadores, excepto IE11 en el momento de la escritura. Simplifica la sintaxis XMLHttpRequest que ve en muchos de los otros ejemplos.

La API incluye mucho más , pero comienza con el fetch()método. Se necesitan dos argumentos:

  1. Una URL o un objeto que representa la solicitud.
  2. Objeto init opcional que contiene el método, encabezados, cuerpo, etc.

OBTENER simple:

const userAction = async () => {
  const response = await fetch('http://example.com/movies.json');
  const myJson = await response.json(); //extract JSON from the http response
  // do something with myJson
}

Recreando la respuesta principal anterior , una POST:

const userAction = async () => {
  const response = await fetch('http://example.com/movies.json', {
    method: 'POST',
    body: myBody, // string or object
    headers: {
      'Content-Type': 'application/json'
    }
  });
  const myJson = await response.json(); //extract JSON from the http response
  // do something with myJson
}
Brendan McGill
fuente
2
¿Cómo se ve la acción del botón con esta solución?
asmaier
3
¿Qué pasa con DELETE y PUT?
Krzysztof
2
@asmaier ¿recibió una respuesta sobre cómo se verá la acción del botón? Gracias
Angel Esguerra
1
button.addEventListener('click', userAction);o<button onclick="userAction()" />
Brendan McGill
105

Su Javascript:

function UserAction() {
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
         if (this.readyState == 4 && this.status == 200) {
             alert(this.responseText);
         }
    };
    xhttp.open("POST", "Your Rest URL Here", true);
    xhttp.setRequestHeader("Content-type", "application/json");
    xhttp.send("Your JSON Data Here");
}

Su acción del botón ::

<button type="submit" onclick="UserAction()">Search</button>

Para obtener más información, visite el siguiente enlace (Actualizado 2017/01/11)

Abhishek
fuente
19
XMLHttpRequest síncrono en el subproceso principal está en desuso debido a sus efectos perjudiciales para la experiencia del usuario final. Para obtener más ayuda, xhr.spec.whatwg.org
jeet.chanchawat
Como está haciendo una llamada sincronizada, debe llamar xhttp.open("POST", "Your Rest URL Here", false);, de lo contrario, xhttp.responseText no contendrá el resultado. Pero como se dijo antes, pronto quedará en desuso.
Alexandre Fenyo
Si se trata de una solicitud POST, ¿dónde publica realmente los datos?
EFC
" xhttp.setRequestHeader("Content-type", "application/json");" - Esto es una mentira. No está pasando ningún JSON al send()método.
Quentin
Has editado este código para que la solicitud ya no sea sincrónica, pero estás intentando leer la respuesta como si lo fuera.
Quentin
17

Aquí hay otra llamada API REST de Javascript con autenticación usando json:

<script type="text/javascript" language="javascript">

function send()
{
    var urlvariable;

    urlvariable = "text";

    var ItemJSON;

    ItemJSON = '[  {    "Id": 1,    "ProductID": "1",    "Quantity": 1,  },  {    "Id": 1,    "ProductID": "2",    "Quantity": 2,  }]';

    URL = "https://testrestapi.com/additems?var=" + urlvariable;  //Your URL

    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = callbackFunction(xmlhttp);
    xmlhttp.open("POST", URL, false);
    xmlhttp.setRequestHeader("Content-Type", "application/json");
    xmlhttp.setRequestHeader('Authorization', 'Basic ' + window.btoa('apiusername:apiuserpassword')); //in prod, you should encrypt user name and password and provide encrypted keys here instead 
    xmlhttp.onreadystatechange = callbackFunction(xmlhttp);
    xmlhttp.send(ItemJSON);
    alert(xmlhttp.responseText);
    document.getElementById("div").innerHTML = xmlhttp.statusText + ":" + xmlhttp.status + "<BR><textarea rows='100' cols='100'>" + xmlhttp.responseText + "</textarea>";
}

function callbackFunction(xmlhttp) 
{
    //alert(xmlhttp.responseXML);
}
</script>


<html>
<body id='bod'><button type="submit" onclick="javascript:send()">call</button>
<div id='div'>

</div></body>
</html>
usuario1713008
fuente
¿No enfrentaste ningún problema de dominio cruzado? Estoy llamando a una API alojada en otro lugar desde localhost y está dando problemas de dominio cruzado.
Harit Vishwakarma
También me enfrento al mismo problema de cors ... por favor ayuda
Nitin Wahale
@HaritVishwakarma: lo hará si la API a la que llama no tiene Access-Control-Allow-Origin para su dominio (localhost). Intente crear su propio proxy, envíe la solicitud al proxy y envíe la solicitud a su destino. Dado que esta será una comunicación de servidor a servidor, la solicitud no se bloqueará (CORS está bloqueado por los navegadores). Envíe esta respuesta con el encabezado allow-origin establecido a todos
sss999
@HaritVishwakarma y NitinWahale y futuros desarrolladores, puede desactivar la seguridad web en su navegador local solo para fines de prueba, sin embargo, esto no funcionará como una solución de producción. Ref aquí: stackoverflow.com/questions/3102819/…
KDT
12
    $("button").on("click",function(){
      //console.log("hii");
      $.ajax({
        headers:{  
           "key":"your key",
     "Accept":"application/json",//depends on your api
      "Content-type":"application/x-www-form-urlencoded"//depends on your api
        },   url:"url you need",
        success:function(response){
          var r=JSON.parse(response);
          $("#main").html(r.base);
        }
      });
});
aayushi
fuente
8

Creo que agregar if (this.readyState == 4 && this.status == 200) para esperar es mejor:

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       // Typical action to be performed when the document is ready:
        var response = xhttp.responseText;
        console.log("ok"+response);
    }
};
xhttp.open("GET", "your url", true);

xhttp.send();
martinwang1985
fuente
Eso no funcionará si el cliente y la API no están en el mismo dominio, ¿verdad?
David Brossard el
0

Antes de intentar poner algo en el front-end del sitio web, abramos una conexión a la API. Lo haremos utilizando objetos XMLHttpRequest, que es una forma de abrir archivos y realizar una solicitud HTTP.

Crearemos una variable de solicitud y le asignaremos un nuevo objeto XMLHttpRequest. Luego, abriremos una nueva conexión con el método open (); en los argumentos especificaremos el tipo de solicitud como GET, así como la URL del punto final de la API. La solicitud se completa y podemos acceder a los datos dentro de la función de carga. Cuando hayamos terminado, le enviaremos la solicitud.
// Cree una variable de solicitud y asígnele un nuevo objeto XMLHttpRequest. solicitud var = nuevo XMLHttpRequest ()

// Open a new connection, using the GET request on the URL endpoint
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true)

request.onload = function () {
  // Begin accessing JSON data here
  }
}

// Send request
request.send()
Roshini Dasari
fuente
1
Se han dado respuestas similares antes. ¿Por qué agregaste tu respuesta? Una breve descripción podría ayudar
slfan
-1

La forma habitual es ir con PHP y ajax. Pero para su requerimiento, a continuación funcionará bien.

<body>

https://www.google.com/controller/Add/2/2<br>
https://www.google.com/controller/Sub/5/2<br>
https://www.google.com/controller/Multi/3/2<br><br>

<input type="text" id="url" placeholder="RESTful URL" />
<input type="button" id="sub" value="Answer" />
<p>
<div id="display"></div>
</body>

<script type="text/javascript">

document.getElementById('sub').onclick = function(){

var url = document.getElementById('url').value;
var controller = null; 
var method = null; 
var parm = []; 

//validating URLs
function URLValidation(url){
if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) {
var x = url.split('/');
controller = x[3];
method = x[4]; 
parm[0] = x[5]; 
parm[1] = x[6];
 }
}

//Calculations
function Add(a,b){
return Number(a)+ Number(b);
}
function Sub(a,b){
return Number(a)/Number(b);
}
function Multi(a,b){
return Number(a)*Number(b);
}  

//JSON Response
function ResponseRequest(status,res){
var res = {status: status, response: res};
document.getElementById('display').innerHTML = JSON.stringify(res);
}


//Process
function ProcessRequest(){

if(method=="Add"){
    ResponseRequest("200",Add(parm[0],parm[1]));
}else if(method=="Sub"){
    ResponseRequest("200",Sub(parm[0],parm[1]));
}else if(method=="Multi"){
   ResponseRequest("200",Multi(parm[0],parm[1]));
}else {
    ResponseRequest("404","Not Found");
 }

}

URLValidation(url);
ProcessRequest();

};
</script>

fuente