使用 JavaScript 调用 API

  • 前言
    • 译者述
    • 作者述
    • 预备知识
    • 本文目标
  • 快速浏览
  • 配置
  • 连接 API
    • 获得 API 端点
    • 通过 HTTP 请求检索数据
    • 处理 JSON 响应
  • 展示数据
  • 总结

前言

译者述

1、原文来自 Tania Rascia 个人网站上的一篇文章:How to Connect to an API with JavaScript。
2、这是一篇较易的入门介绍文章,发布于2017年12月7日。
3、翻译中会尽量遵照原意,也会加入译者的技术注释,以及选择更符合汉语文法的译句。


作者述

众所周知啊,使用 JavaScript 的大部分工作都是调用 API 。作为一个菜鸡,你可能被告知:多用用 API 就能知道用法了。如果你看到 API 的文档,但仍举手无措,那么这篇文章正好适合你。

我们将使用纯粹的 javaScript 编写一个非常简单的 web app,它从 API 中检索信息并在页面上展示。不需要服务端、依赖、构建工具或者其他复杂的内容。

  • 在线示例
  • GitHub 源码

预备知识

  • 基本了解 HTML 和 CSS
  • 基本了解 JS 语法和数据类型
  • 基本了解 JSON 和 JS 对象 工作原理(这篇链接的文章有完全的介绍)

其他知识下文会提及。

本文目标

我们将从头开始编写这个链接到吉卜力工作室 API 的应用,检索数据并在网站前端展示。这并不意味着需要用到 APIs 或 REST 的大量资源——只需要最少可用的数据来构建应用即可。我们将会学到:

  • 什么是 API 。
  • 学会使用 JavaScript 发出 HTTP GET 请求。
  • 学会使用 JavaScript 创建一个用于展示的 HTML 元素。

表现的效果如图所示:

下面就开始了。

快速浏览

API 全称为 Application Program Interface,可以定义为:各种软件组件之间的一组通信方法。换句话说,一个 API 允许一个软件和另一个软件通信。

我们将特别关注 Web API,它能允许 Web 服务器与第三方软件交互。在这种情况下,Web 服务器使用 HTTP 请求与包含 JSON 数据的公开可用 URL 端点通信。如果现在对此感到困惑,那么读完本文就会明白了。

你可能很熟悉 CRUD app 的概念,它代表 Create、Read、Update、Delete(创建、读取、更新、删除)。任何编程语言都可以用各种方法来实现 CRUD app。一个 Web API 使用的 HTTP 请求对应着 CRUD 的动词。

Action HTTP Method Description
Create POST Creates a new resource
Read GET Retrieves a resource
Update PUT/PATCH Updates an existing resource
Delete DELETE Deletes a resource

假如你听说过 REST 和 REST 风格 API,它其实只是指一组遵循特定的架构风格的标准。大多数 web 应用都是这样,或者以符合 REST 标准为目标。总而言之,有很多术语、缩写、概念需要理解:HTTP、API、REST,所以感到困惑和受挫是正常的,特别是当 API 文档默认你已经知道这些知识的时候。

配置

我们的目标是什么?得到所有吉卜力工作室电影的数据,然后在网格中展示标题和描述信息。这里有个背景知识,吉卜力工作室是一家日本动画工作室,制作了几部电影,例如《千与千寻》——我的朋友克雷格启发我用它作为例子。

我们将从在新目录中创建 index.html 文件开始。项目最后只会包含 index.html 、 style.css 和 scripts.js 。这个 HTML 结构只是链接到 CSS 和 JavaScript 文件,加载字体、包含一个 id=“root” 的 div 元素。它是完整的,不用再更改。我们将使用 JavaScript 添加所有要出现的内容。

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Ghibli App</title><link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet" /><link href="style.css" rel="stylesheet" /></head><body><div id="root"></div><script src="scripts.js"></script></body>
</html>

由于本文关注的是 APIs 和 JavaScript 的概念,所以我不会解释 CSS 的工作原理。我们将新建一个 style.css 来创建网格。为了简洁处理,我只在下面列出了最相关的 CSS 结构,但你可以在这里复制完整的CSS代码。

#root {max-width: 1200px;margin: 0 auto;
}.container {display: flex;flex-wrap: wrap;
}.card {margin: 1rem;border: 1px solid gray;
}@media screen and (min-width: 600px) {.card {flex: 1 1 calc(50% - 2rem);}
}@media screen and (min-width: 900px) {.card {flex: 1 1 calc(33% - 2rem);}
}

现在我们已经配置了 HTML 和 CSS,然后你可以创建 scripts.js,我们将从那一步继续。

连接 API

先来看看吉卜力工作室 API 文档,他可以帮助开发人员了解怎样使用 HTTP 请求进行资源交互,这对我们来说是非常有帮助的。由于 API 可以通过许多不同的方法访问—— JavaScript, PHP, Ruby, Python 等等 —— 大多数 API 的文档往往不会给出如何连接的具体说明。

从文档中得知,我们可以通过 curl 和常规 REST 调用发出请求,只是目前可能还不理解怎么操作。

获得 API 端点

首先,让我们转到电影部分。在右边你能看到 GET /films,它会展示 API 端点的 url,https://ghibliapi.herokuapp.com/films。点击该链接将显示一个 JSON 格式的对象数组。

如果你的浏览器上没有用于查看 JSON 文件的扩展,那么现在就添加一个,例如 JSON View。这将使读取 JSON 变得非常非常容易。请记住,如果你从未使用过 JSON,先阅读这篇必备的文章。

通过 HTTP 请求检索数据

在数据放到网站前端之前,先打开一个 API 连接。我们使用 XMLHttpRequest 对象,它可以打开文件、创建 HTTP 请求。

创建一个 request 并分配一个 XMLHttpRequest 对象给它。然后用 open() 方法打开一个新的连接,其中的参数需要指定请求类型为 GET,以及设置 API 端的 URL。请求完成后,我们可以访问 onload 函数中的数据。做完这些后,就可以发送请求了。

// 创建一个 request 并分配一个 XMLHttpRequest 对象给它
var request = new XMLHttpRequest()// 用 open() 方法打开一个新的连接,其中的参数需要指定请求类型为 GET,以及设置 API 端的 URL
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true)request.onload = function () {// 访问 onload 函数中的数据
}// 发送请求
request.send()

此外,也可以使用 fetch API 和 async/await 来实现。

function getData() {const response = await fetch('https://ghibliapi.herokuapp.com/films')const data = await response.json()
}

处理 JSON 响应

现在我们接收到了从 HTTP 请求返回的响应,然后就可以处理它了。但是,响应是 JSON 格式的,我们需要将 JSON 转换为 JavaScript 对象才能使用。

使用 JSON.parse() 来序列化响应,然后创建 data 变量 —— JavaScript 数组对象,包含全部 JSON。再使用 forEach() 打印出全部的电影标题,验证处理操作的正确性。

// 使用 JSON.parse() 来序列化响应
var data = JSON.parse(this.response)data.forEach(movie => {// 打印出全部的电影标题console.log(movie.title)
})

查看控制台,可以看到20条电影数据,这说明成功了。

还有一件事:缺少一些错误处理的方法。如果使用了错误的 URL,或者资源本身有问题,导致没有显示任何内容,该怎么办?当发出 HTTP 请求时,返回响应中会带有 HTTP 状态码。“404”是最常见的响应,表示资源未找到,“200 OK” 是表示请求成功。

让我们将代码包装在 if 语句中,对 [200,399) 范围内的任何响应进行处理,并在请求失败时打印错误。你可以把 URL 弄乱测试看看。

// 开始访问 JSON 数据
var data = JSON.parse(this.response)if (request.status >= 200 && request.status < 400) {data.forEach(movie => {console.log(movie.title)})
} else {console.log('error')
}

下面是到目前为止的全部代码,scripts.js 文件。

var request = new XMLHttpRequest()request.open('GET', 'https://ghibliapi.herokuapp.com/films', true)
request.onload = function () {// Begin accessing JSON data herevar data = JSON.parse(this.response)if (request.status >= 200 && request.status < 400) {data.forEach(movie => {console.log(movie.title)})} else {console.log('error')}
}request.send()

我们已经成功地使用 GET HTTP 请求来检索(或使用) API 端点,该 API 端点由 JSON 格式的数据组成。但是,我们仍然停留在控制台上——想要在网站的前端显示这些数据,需要通过修改 DOM 来实现。

展示数据

为了在网站前端展示信息,我们将使用 DOM,它实际上是一种 API,允许 JavaScript 与 HTML 通信。如果你没有用过 DOM,我为 DigitalOcean 写了《用 JavaScript 理解和修改 DOM 》,阐明了 DOM 是什么以及 DOM 与 HTML 源代码的区别。

(译者补充:DigitalOcean 是一家成立于2012年的总部设置在纽约的云主机商家。)

最后,我们的页面将包含一个 logo 和多个卡片——每张卡片是一部电影,有一个标题和一个段落,包含了电影名称和简介。下面是它的样子,只加载了必要的CSS:

还记得吗?我们的 index.html 现在只有一个 root div —— < div id=“root” / >,用 getElementById() 来访问它。我们现在可以简单地删除之前编写的所有代码,稍后将重新添加这些代码。

const app = document.getElementById('root')

如果你不是100%确定 getElementById() 做了什么,在上面的代码中打印 app: console.log(app),有助于理解过程中发生的事情。网站首要的是 logo,这是一个 img 元素。我们将使用 createElement() 创建图像元素。

const logo = document.createElement('img')

一个空的 img 没什么用,所以我们用 src 属性设置图片。

logo.src = 'logo.png'

我们将创建另一个 div 元素并将其 class 属性设置为 container。

const container = document.createElement('div')
container.setAttribute('class', 'container')

现在我们有了一个 img 和一个 div,我们只需要把它们放在网站上。我们将使用 appendChild() 方法将logo img 和容器 div 附加到 app root。

app.appendChild(logo)
app.appendChild(container)

下面是完整的代码:

const app = document.getElementById('root')const logo = document.createElement('img')
logo.src = 'logo.png'const container = document.createElement('div')
container.setAttribute('class', 'container')app.appendChild(logo)
app.appendChild(container)

保存后,在网站的前端,你会看到以下内容。

<div id="root"><img src="logo.png" /><div class="container"></div>
</div>

这是 Elements 中显示的,而不是在 HTML 源代码中存在——正如我链接的 DOM 文章中所解释的那样。
现在我们要把之前的代码粘贴回去。最后要根据之前控制台打印出来的东西创建卡片元素。
虽然粘贴全部代码,但是我们只关注 forEach() 中的内容。

data.forEach(movie => {console.log(movie.title)console.log(movie.description)
})

我们使用 textContent 将 API 返回数据中的文本设置到 HTML 元素中。为了保持卡片元素宽度一致,我们使用 substring() 来限制 p 元素中的段落长度。

data.forEach(movie => {// Create a div with a card classconst card = document.createElement('div')card.setAttribute('class', 'card')// Create an h1 and set the text content to the film's titleconst h1 = document.createElement('h1')h1.textContent = movie.title// Create a p and set the text content to the film's descriptionconst p = document.createElement('p')movie.description = movie.description.substring(0, 300) // Limit to 300 charsp.textContent = `${movie.description}...` // End with an ellipses// Append the cards to the container elementcontainer.appendChild(card)// Each card will contain an h1 and a pcard.appendChild(h1)card.appendChild(p)
})

同理,前端 error 打印部分也将被替换为 marquee 元素!(我这样做只是为了好玩和演示,不要在任何实际应用中使用marquee,也不要把我的话当真。)

const errorMessage = document.createElement('marquee')
errorMessage.textContent = `Gah, it's not working!`
app.appendChild(errorMessage)

我们做完了!下面是最终的scripts.js代码。

const app = document.getElementById('root')const logo = document.createElement('img')
logo.src = 'logo.png'const container = document.createElement('div')
container.setAttribute('class', 'container')app.appendChild(logo)
app.appendChild(container)var request = new XMLHttpRequest()
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true)
request.onload = function () {// Begin accessing JSON data herevar data = JSON.parse(this.response)if (request.status >= 200 && request.status < 400) {data.forEach(movie => {const card = document.createElement('div')card.setAttribute('class', 'card')const h1 = document.createElement('h1')h1.textContent = movie.titleconst p = document.createElement('p')movie.description = movie.description.substring(0, 300)p.textContent = `${movie.description}...`container.appendChild(card)card.appendChild(h1)card.appendChild(p)})} else {const errorMessage = document.createElement('marquee')errorMessage.textContent = `Gah, it's not working!`app.appendChild(errorMessage)}
}request.send()

之后使用完整的 CSS 样式,这里是最终产品的样子。

同样,这里有链接可以查看在线 app 和源代码。

  • 查看在线实例
  • 源代码

总结

恭喜,你使用纯 JavaScript 通过 HTTP 请求连接到 API。希望你能够更好地理解什么是 API 端点,浏览器如何通过请求和响应与第三方 API 数据通信,如何将 JSON 解析为 JavaScript 能够理解的数组和对象,以及如何只用 JavaScript 构建前端。

我们做到了这一切,而不用担心 Node.js、npm、Webpack、React、Angular、构建工具、jQuery、Axios 和其他流行的开发术语、依赖项和框架,这些东西可能会让你对最简单的形式下发生的事情感到困惑。

我希望这篇文章对你有用,也欢迎分享。

使用 JavaScript 调用 API相关推荐

  1. atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...

  2. java swing调用H5_atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97...

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1.实现html5化界面的要解决的策略 1.1.Js交互 Firefox与Chro ...

  3. JavaScript调用原生API获取手机型号

    跨平台技术简介 针对原生开发面临问题,人们一直都在努力寻找好的解决方案,而时至今日,已经有很多跨平台框架,根据其原理,主要分为三类: H5+原生(Cordova.Ionic.微信小程序) JavaSc ...

  4. javascript调用百度地图api

    百度地图提供sdk,javascript api等多种客户端调用方式,通常在网页上用的比较多,也就是javascript api,这里根据自己的使用,简单介绍一下如何快速使用javascript调用百 ...

  5. 百度短语音识别api(JavaScript调用)

    百度短语音识别api(JavaScript调用) 前言 页面效果预览 配置代理 获取百度鉴权机制token请求 百度短语音识别请求 获取百度Access Token 调用短语音识别接口 使用本地文件测 ...

  6. web api接口开发实例_小程序开发如何调用 API 接口,以豆瓣电影为例

    API 调用是开发者在小程序开发过程中经常会遇到的问题,本期我们以为调用豆瓣电影 API 为例具体来看 API 的调用过程以及常见的一些问题. 测试用到的小程序是「电影周周看」,内容来自清华大学软件学 ...

  7. 借助 CORS 从 JavaScript 使用 API 应用

    应用服务提供内置的跨域资源共享 (CORS) 支持,可让 JavaScript 客户端对 API 应用中托管的 API 进行跨域调用.应用服务允许配置对 API 的 CORS 访问,无需在 API 中 ...

  8. JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)

    JavaScript + Audio API自制简易音乐播放器(详细完整版) ** 音乐播放器的功能清单如下: ** 1.点击暂停按钮,歌曲暂停 2.点击播放按钮,歌曲播放 3.单曲循环与取消单曲循环 ...

  9. 【学习总结】-Apsara Clouder专项技能认证:实现调用API接口学习总结

    Apsara Clouder专项技能认证:实现调用API接口-学习总结 API的概念: API的特点: API的分类: 为什么要使用API 阿里云API市场 API请求与认证 Web API协议 HT ...

最新文章

  1. Windows下dump文件生成与分析
  2. R主成分分析PCA示例
  3. Selenium常用API的使用java语言之7-控制浏览器操作
  4. JS DOM节点增删改查 属性设置
  5. 拆解拼多多、趣头条、小红书背后的上海互联网基因
  6. Mean Shift具体介绍
  7. C语言编译器Visual Studio官方正版下载安装
  8. 如何用笔记本组建家庭点歌系统
  9. creo数控编程怎么样_CREO 3.0中文版数控加工高手必备118招
  10. python读文件的方法open,file,with open
  11. 【前端】基于layui写的一个高级搜索(筛选)功能
  12. 操作STM32单片机蜂鸣器模块演奏歌曲《北京欢迎你》
  13. Smart-api开源api接口管理平台
  14. 1898: [Zjoi2005]Swamp 沼泽鳄鱼
  15. Docker 上传镜像到docker hub
  16. HTML5,js制作坦克大战
  17. xampp开启GD2绘图
  18. zephir-php函数和异常处理
  19. Oracle数据库对小数点的操作
  20. 博图程序需要手动同步_西门子博途S7-1200 PWM 功能组态及编程方法

热门文章

  1. 2019最新迅为-i.MX6Q开发板资料目录
  2. 熊猫烧香的病毒制作源码
  3. 网页点击弹出QQ对话框
  4. Html+Css+js实现春节倒计时效果
  5. 如何设置无需fn直接按F1~F10
  6. 双显示器(集成显卡不能显示,但独立显卡可以)
  7. linux 硬盘克隆diskgen,DiskGenius-硬盘分区及数据恢复软件-DiskGenius下载 v5.2.0.884官方版-完美下载...
  8. 字符编码问题总结(11年3月1日)
  9. 打开潘多拉的魔盒——软件设计过程(1)——序
  10. 7、em/px/rem/vh/vw区别?