如何从JavaScript调用REST Web服务API?

303

我有一个带有按钮的HTML页面。当单击该按钮时,我需要调用REST Web服务API。我已经在网上搜索了所有地方,但完全没有头绪。有人能给我个提示/入门吗?非常感谢。


2
你对REST服务的调用只是向服务器发出的请求,我猜它将会是一个ajax请求。例如使用jQuery:http://api.jquery.com/jquery.ajax/ - ikos23
10个回答

380

我很惊讶没人提到新的Fetch API,目前除了IE11以外的所有浏览器都支持它。它简化了在其他示例中看到的XMLHttpRequest语法。

API包括更多内容,但首先使用fetch()方法。 它有两个参数:

  1. URL或表示请求的对象。
  2. 可选的初始化对象,包含方法、头部、正文等。

简单的GET请求:

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
}

重新制作之前的最佳答案,一个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
}

3
使用这个解决方案,按钮的操作是什么样的? - asmaier
10
DELETE和PUT怎么处理? - Krzysztof
2
@asmaier,你得到关于按钮操作的答案了吗?谢谢。 - Angel
6
button.addEventListener('click', userAction); 或者 <button onclick="userAction()" /> 的意思是在点击按钮时执行名为 userAction 的函数。 - Brendan McGill
在CosmosDB中,是否有一种方法可以在存储过程或UDF中使用类似的JavaScript? - user1440703

127

你的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");
}

您的按钮操作:

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

了解更多信息,请通过以下链接查看(更新于2017/01/11)


22
同步XMLHttpRequest已经被弃用,因为它对最终用户的体验有害。了解更多帮助,请参考http://xhr.spec.whatwg.org/。 - jeet.chanchawat
由于您正在进行同步调用,因此您需要调用 xhttp.open("POST", "这里是您的 REST URL", false);,否则 xhttp.responseText 将不包含结果。但如前所述,它将很快被弃用。 - Alexandre Fenyo
如果这是一个POST请求,你实际上将数据发布在哪里? - EFC
"xhttp.setRequestHeader("Content-type", "application/json");" — 这是个谎言。你没有向 send() 方法传递任何 JSON。 - Quentin
您已编辑此代码,使请求不再同步,但您正在尝试读取响应,就好像它仍是同步的。 - Quentin
1
当你尝试使用Service Workers时,你会后悔使用XMLHttpRequest对象而不是fetch()。对于旧版浏览器,有fetch()的polyfills可供使用。学习使用fetch()。 - John Deighan

22

这是另一个使用 JSON 进行身份验证的 JavaScript REST API 调用:

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

你没有遇到跨域问题吗?我正在从本地主机调用托管在其他地方的 API,但它会产生跨域问题。 - Harit Vishwakarma
我也遇到了同样的CORS问题,请帮忙。 - Nitin Wahale
如果你调用的API没有为你的域名(localhost)设置Access-Control-Allow-Origin,那么它就会出现这种情况。尝试创建自己的代理,将请求发送到代理并将请求转发到目标地址。由于这将是服务器之间的通信,因此请求不会被阻止(浏览器会阻止CORS)。将允许来源头设置为所有内容,并将此响应发送回去。 - sss999
@HaritVishwakarma 和 NitinWahale,以及未来的开发者们,你可以为测试目的在本地浏览器上禁用网络安全性,但这并不能作为生产解决方案。参考链接:https://dev59.com/QnA75IYBdhLWcg3wy8Ui - KDT

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

11

我认为加上 if (this.readyState == 4 && this.status == 200) 这个条件来等待会更好:

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

如果客户端和API不在同一个域中,那么这样做是行不通的,对吧? - David Brossard

1
如果有帮助的话,如果你可以接受使用外部库,我可以保证Axios是一个不错的选择,它有一个相当简洁的API和丰富的文档来处理REST调用,下面是一个示例:
const axios = require('axios');

axios.get('/user?ID=12345')
  .then(function (response) {
    // handle success
    console.log(response);
  });

0
到目前为止,对我来说最容易使用的是Axios。您可以下载节点模块或在简单项目中使用CDN。
CDN:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

GET/POST的代码示例:

let postData ={key: "some value"}

    axios.get(url).then(response =>{
    //Do stuff with the response.
    })
        
    axios.post(url, postData).then(response=>{
    //Do stuff with the response.
    });

0

在我们尝试将任何东西放在网站前端之前,让我们先打开与API的连接。我们将使用XMLHttpRequest对象来实现这一点,这是一种打开文件和发出HTTP请求的方式。

我们将创建一个请求变量并将一个新的XMLHttpRequest对象分配给它。然后,我们将使用open()方法打开一个新的连接 - 在参数中,我们将指定请求类型为GET以及API端点的URL。请求完成后,我们可以在onload函数中访问数据。完成后,我们将发送请求。
// 创建一个请求变量并将一个新的XMLHttpRequest对象分配给它。 var request = new 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()

1
之前已经有类似的答案了,为什么要添加你的答案?简短的描述可能会有所帮助。 - slfan

-2
毫无疑问,最简单的方法是在HTML中使用一个不可见的FORM元素来指定所需的REST方法。然后可以使用JavaScript将参数插入到input type=hidden值字段中,并且可以使用一行JavaScript从按钮点击事件侦听器或onclick事件提交表单。这里是一个示例,假设REST API在文件REST.php中:
<body>
<h2>REST-test</h2>
<input type=button onclick="document.getElementById('a').submit();"
    value="Do It">
<form id=a action="REST.php" method=post>
<input type=hidden name="arg" value="val">
</form>
</body>

请注意,此示例将使用页面 REST.php 的输出替换页面。 如果您希望在当前页面上没有可见效果的情况下调用API,我不确定如何修改此示例。但这确实很简单。

-4

通常的方法是使用PHP和ajax。但对于您的要求,以下方法也可以正常工作。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接