javascript - 显示请稍候或加载程序使用 javascript-REST API 调用
问题描述
我正在编写一个 chrome 扩展来将数据从扩展发送到公开的 REST 服务。当我收到来自 API 的响应时,我正在显示一条状态消息。我想在执行 API 调用时显示请稍候或加载程序,主要是告诉用户尚未从服务器收到响应或服务器本身已关闭。由于它是一个异步调用,我不确定将代码放在哪里来显示加载器。我需要使用回调函数吗?这是我的代码-
HTML:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h2>Send data to system Application</h2>
<form action="/action_page.php">
<p>Please select:</p>
<input type="radio" id="Credentials" name="CB" value="Credentials">
<label for="Credentials">Credentials</label><br>
<input type="radio" id="GeneralInformation" name="CB" value="GeneralInformation">
<label for="GeneralInformation">General Information</label><br>
<br>
<div id="ifCredentials" style="display:none">
<form>
Username <input type="text" id="Username" style="line-height:3em"> <br><br>
Password <input type="text" id="Password" style="line-height:3em"> <br><br>
URL <input type="text" id="URL" style="line-height:3em"> <br><br>
Environment <input type="text" id="Environment" style="line-height:3em"> <br><br>
Labels <input type="text" id="SVLabel" style="line-height:3em"> <br><br>
</form>
</div>
<div id="ifGeneralInformation" style="display:none">
<form>
Description <input type="text" id="Description" style="line-height:3em"> <br><br>
URL <input type="text" id="GIURL" style="line-height:3em"> <br><br>
Labels <input type="text" id="GILabel" style="line-height:3em"> <br><br>
</form>
</div>
<br>
<input type="submit" id="submitButton" value="Submit">
<div id="loader" style="display:none">Please wait... </div>
<div id="RESTStatus" style="display:none">
<br> Status: <label id="RESTINFO">f</label>
</div>
</form>
<script src="script.js"></script>
</body>
</html>
JAVASCRIPT:
document.getElementById("Credentials").addEventListener("click", showRightData);
document.getElementById("GeneralInformation").addEventListener("click", showRightData);
document.getElementById("submitButton").addEventListener("click", callAPI);
function showRightData() {
console.log("hel");
if (document.getElementById('Credentials').checked) {
document.getElementById('ifCredentials').style.display = 'block';
document.getElementById('ifGeneralInformation').style.display = 'none';
}
else if (document.getElementById('GeneralInformation').checked)
{
document.getElementById('ifGeneralInformation').style.display = 'block';
document.getElementById('ifCredentials').style.display = 'none';
chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => {
let url = tabs[0].url;
// use `url` here inside the callback because it's asynchronous!
document.getElementById('GIURL').value=url;
});
}
else
{
document.getElementById('ifGeneralInformation').style.display = 'none';
document.getElementById('ifCredentials').style.display = 'none';
}
}
/*window.onload = function()
{
document.getElementById('GIURL').value=window.location.toString();
}*/
function callAPI() {
const req = new XMLHttpRequest();
const baseUrl = "http://localhost:8080/api/v1/cases";
req.open("POST", baseUrl, true);
req.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
if (document.getElementById('Credentials').checked) {
req.send(JSON.stringify(
{
"caseTypeID": "CB-systems-Work-Artifact",
"processID": "pyStartCase",
"parentCaseID": "",
"content": {
"ArtifactData": {
"ArtifactType":"Password",
"ArtifactUsername":document.getElementById('Username').value,
"ArtifactPassword":document.getElementById('Password').value,
"ArtifactURL":document.getElementById('URL').value,
"ArtifactEnvironment":document.getElementById('Environment').value,
"ArtifactLabels":document.getElementById('SVLabel').value
}
}
}
));
}
else if (document.getElementById('GeneralInformation').checked)
{
req.send(JSON.stringify(
{
"caseTypeID": "CB-systems-Work-Artifact",
"processID": "pyStartCase",
"parentCaseID": "",
"content": {
"ArtifactData": {
"ArtifactType":"General",
"Description":document.getElementById('Description').value,
"ArtifactURL":document.getElementById('GIURL').value,
"ArtifactLabels":document.getElementById('GILabel').value
}
}
}
));
}
req.onreadystatechange = function() { // Call a function when the state changes.
if (this.readyState === XMLHttpRequest.DONE && this.status == 201) {
document.getElementById('RESTINFO').innerHTML = "Successfully sent data to the system! API status: "+this.status;
document.getElementById('RESTStatus').style.display = 'block';
}
else
{
document.getElementById('RESTINFO').innerHTML = "Failed to update the system! API Status: "+this.status;
document.getElementById('RESTStatus').style.display = 'block';
}
}
req.onerror = function() {
document.getElementById('RESTINFO').innerHTML = "There has been an error. The status code is "+req.status;
document.getElementById('RESTStatus').style.display = 'block';
}
}
解决方案
看来您已经设置了大部分必要的代码。您需要做的就是添加行以在适当的位置显示/隐藏加载程序。
要首先显示它,请添加以下内容:
document.getElementById('loader').style.display = 'block';
就在你的两个req.send
电话之前。(您可以在函数开始时只添加一次,但似乎您只在两种情况之一中发送请求,所以这必须在if
语句中 - 如果两者都存在,您可能希望向用户显示一些消息其中没有向他们解释什么是错误的以及如何实际提出请求。)
然后用这个隐藏它:
document.getElementById('loader').style.display = 'none';
收到回复时。在这种情况下,我认为您的代码不正确,因为您假设一个readystatechange
事件必然意味着请求已完成(成功与否),而实际上它发生在到达最终状态的各个阶段 - 请参阅此处的文档。
在回调函数中你应该做的onreadystatechange
是这样的:
req.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE) {
// request is finished, so hide loader:
document.getElementById('loader').style.display = 'none';
if (req.status === 201) {
// code for successful response
}
else {
// code to handle unsuccessful response
}
}
}
请注意,我使用req.status
而不是, 以避免内部回调this.status
的众所周知的问题。this
上面的粗略大纲应该按照您的意愿进行 - 但您的大部分代码都可以简化和改进。我强烈建议使用现代且广泛支持的基于 Promise 的fetch API,而不是相当老式的XMLHttpRequest
.
推荐阅读
- java - 在 JSP 中选择不向 java 控制器发送值
- python - 如何遍历Django中的所有孩子?
- powershell - 将 PSObject 正则表达式过滤结果与初始值名称相结合
- python - 如何在 Python 中获得 Delaunay Triangle 的最近点?
- selenium - Selenium 在测试期间单击文本字段失败,通过单命令测试
- java - 本机 Java 中的 2D 游戏图形:Canvas 与 JComponent
- vb.net - 如何使文本框只接受整数?VB
- sql - ERP:数据库设计方法
- code-snippets - 如何在网站中插入动态代码片段?
- postgresql - 使用 openlayers 将空的多行字符串保存到 postgis