fix: Add Api challenges - Chinese translation (#35164)
* fix: Add Api challenges - Chinese translation * fix: md formatting * fix: md formatting
This commit is contained in:
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf4
|
||||
title: Chain Middleware to Create a Time Server
|
||||
localeTitle: 链中间件创建时间服务器
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>使用<code>app.METHOD(path, middlewareFunction)</code>可以在特定路径上安装<code>app.METHOD(path, middlewareFunction)</code> 。中间件也可以在路由定义中链接。 <code>0</code>查看以下示例:
|
||||
<blockquote>app.get('/user', function(req, res, next) {<br> req.user = getTheUserSync(); // Hypothetical synchronous operation<br> next();<br>}, function(req, res) {<br> res.send(req.user);<br>})</blockquote> <code>0</code>此方法可用于将服务器操作拆分为较小的单元。这导致了更好的应用程序结构,以及在不同位置重用代码的可能性。此方法还可用于对数据执行某些验证。在中间件堆栈的每个点,您可以阻止当前链的执行,并将控制权传递给专门用于处理错误的函数。或者您可以将控制权传递给下一个匹配的路径,以处理特殊情况。我们将在高级Express部分中看到如何。 <code>0</code>在路径<code>app.get('/now', ...)</code>链中间件函数和最终处理程序。在中间件功能中,您应该在<code>req.time</code>键中将当前时间添加到请求对象。您可以使用<code>new Date().toString()</code> 。在处理程序中,使用JSON对象进行响应,采用结构<code>{time: req.time}</code> 。 <code>0</code>提示:如果不链接中间件,测试将无法通过。如果将函数挂载到其他位置,即使输出结果正确,测试也会失败。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: / now端点应该已经安装了中间件
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/_api/chain-middleware-time'').then(data => { assert.equal(data.stackLength, 2, ''"/now" route has no mounted middleware''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
- text: / now端点应返回从现在起+/- 20秒的时间
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/_api/chain-middleware-time'').then(data => { var now = new Date(); assert.isAtMost(Math.abs(new Date(data.time) - now), 20000, ''the returned time is not between +- 20 secs from now''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf8
|
||||
title: Get Data from POST Requests
|
||||
localeTitle: 从POST请求中获取数据
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>在路径<code>/name</code>处安装POST处理程序。它和以前一样。我们在html首页中准备了一个表单。它将提交练习10(查询字符串)的相同数据。如果正确配置了body-parser,您应该在对象<code>req.body</code>找到参数。看看通常的库示例:
|
||||
<blockquote>route: POST '/library'<br>urlencoded_body: userId=546&bookId=6754 <br>req.body: {userId: '546', bookId: '6754'}</blockquote> <code>0</code>使用与以前相同的JSON对象进行响应: <code>{name: 'firstname lastname'}</code> 。使用我们在应用程序首页中提供的html表单测试您的端点是否正常工作。 <code>0</code>提示:除了GET和POST之外,还有其他几种http方法。按照惯例,http动词与您要在服务器上执行的操作之间存在对应关系。传统的映射是:
|
||||
POST(有时是PUT) - 使用随请求发送的信息创建新资源,
|
||||
GET - 读取现有资源而不修改它,
|
||||
PUT或PATCH(有时是POST) - 使用数据更新资源已发送,
|
||||
DELETE =>删除资源。 <code>0</code>还有一些其他方法用于协商与服务器的连接。除了GET之外,上面列出的所有其他方法都可以有一个有效载荷(即数据进入请求体)。身体解析器中间件也适用于这些方法。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '测试1:您的API端点应使用正确的名称进行响应'
|
||||
testString: 'getUserInput => $.post(getUserInput(''url'') + ''/name'', {first: ''Mick'', last: ''Jagger''}).then(data => { assert.equal(data.name, ''Mick Jagger'', ''Test 1: "POST /name" route does not behave as expected'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
- text: '测试2:您的API端点应使用正确的名称进行响应'
|
||||
testString: 'getUserInput => $.post(getUserInput(''url'') + ''/name'', {first: ''Keith'', last: ''Richards''}).then(data => { assert.equal(data.name, ''Keith Richards'', ''Test 2: "POST /name" route does not behave as expected'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf6
|
||||
title: Get Query Parameter Input from the Client
|
||||
localeTitle: 从客户端获取查询参数输入
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>从客户端获取输入的另一种常用方法是使用查询字符串对路径路径后的数据进行编码。查询字符串由问号(?)分隔,并包括field = value couple。每对夫妇用和号(&)隔开。 Express可以解析查询字符串中的数据,并填充对象<code>req.query</code> 。某些字符不能在URL中,它们必须以<a href='https://en.wikipedia.org/wiki/Percent-encoding' target='_blank'>不同的格式</a>编码才能发送它们。如果您使用JavaScript中的API,则可以使用特定方法对这些字符进行编码/解码。
|
||||
<blockquote>route_path: '/library'<br>actual_request_URL: '/library?userId=546&bookId=6754' <br>req.query: {userId: '546', bookId: '6754'}</blockquote> <code>0</code>构建一个以<code>GET /name</code>挂载的API端点。使用结构<code>{ name: 'firstname lastname'}</code>回复JSON文档。名字和姓氏参数应该在查询字符串中编码,例如<code>?first=firstname&last=lastname</code> 。 <code>0</code>提示:在下面的练习中,我们将在相同<code>/name</code>路径路径的POST请求中接收数据。如果需要,可以使用方法<code>app.route(path).get(handler).post(handler)</code> 。此语法允许您在同一路径路径上链接不同的动词处理程序。您可以节省一些打字,并拥有更清晰的代码。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '测试1:您的API端点应使用正确的名称进行响应'
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/name?first=Mick&last=Jagger'').then(data => { assert.equal(data.name, ''Mick Jagger'', ''Test 1: "GET /name" route does not behave as expected'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
- text: '测试2:您的APi端点应以正确的名称响应'
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/name?last=Richards&first=Keith'').then(data => { assert.equal(data.name, ''Keith Richards'', ''Test 2: "GET /name" route does not behave as expected'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf5
|
||||
title: Get Route Parameter Input from the Client
|
||||
localeTitle: 从客户端获取路由参数输入
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>构建API时,我们必须允许用户与我们沟通他们希望从我们的服务中获得什么。例如,如果客户端请求有关存储在数据库中的用户的信息,他们需要一种方法让我们知道他们感兴趣的用户。实现此结果的一种可能方法是使用路由参数。路由参数是URL的命名段,由斜杠(/)分隔。每个段捕获URL的与其位置匹配的部分的值。捕获的值可以在<code>req.params</code>对象中找到。
|
||||
<blockquote>route_path: '/user/:userId/book/:bookId'<br>actual_request_URL: '/user/546/book/6754' <br>req.params: {userId: '546', bookId: '6754'}</blockquote> <code>0</code>构建一个安装在路径<code>GET /:word/echo</code>的回显服务器。使用结构<code>{echo: word}</code>响应JSON对象。您可以在<code>req.params.word</code>找到要重复的<code>req.params.word</code> 。您可以从浏览器的地址栏测试您的路线,访问一些匹配的路线,例如您的-app-rootpath / freecodecamp / echo
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: '测试1:您的echo服务器应该正确重复单词'
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/eChOtEsT/echo'').then(data => { assert.equal(data.echo, ''eChOtEsT'', ''Test 1: the echo server is not working as expected'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
- text: '测试2:您的echo服务器应该正确重复单词'
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/ech0-t3st/echo'').then(data => { assert.equal(data.echo, ''ech0-t3st'', ''Test 2: the echo server is not working as expected'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf3
|
||||
title: Implement a Root-Level Request Logger Middleware
|
||||
localeTitle: 实现根级请求记录器中间件
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>在我们介绍<code>express.static()</code>中间件函数之前。现在是时候更详细地看看中间件是什么了。中间件函数是带有3个参数的函数:请求对象,响应对象和应用程序请求 - 响应周期中的下一个函数。这些函数执行一些可能对应用程序产生副作用的代码,并且通常会向请求或响应对象添加信息。当满足某些条件时,它们还可以结束发送响应的循环。如果他们没有发送响应,当他们完成时,他们开始执行堆栈中的下一个函数。触发调用第三个参数<code>next()</code> 。 <a href='http://expressjs.com/en/guide/using-middleware.html' target='_blank'>快递文档</a>中的更多信息。 <code>0</code>查看以下示例:
|
||||
<blockquote>function(req, res, next) {<br> console.log("I'm a middleware...");<br> next();<br>}</blockquote> <code>0</code>假设我们在路线上安装了此功能。当请求与路由匹配时,它会显示字符串“我是中间件......”。然后它执行堆栈中的下一个函数。 <code>0</code>在本练习中,我们将构建一个根级中间件。正如我们在挑战4中所见,要在根级别安装中间件功能,我们可以使用方法<code>app.use(<mware-function>)</code> 。在这种情况下,将对所有请求执行该功能,但您也可以设置更具体的条件。例如,如果您希望仅为POST请求执行某个函数,则可以使用<code>app.post(<mware-function>)</code> 。所有http动词都有类似的方法(GET,DELETE,PUT,...)。 <code>0</code>构建一个简单的记录器。对于每个请求,它应该在控制台中登录一个字符串,采用以下格式: <code>method path - ip</code> 。示例如下: <code>GET /json - ::ffff:127.0.0.1</code> 。请注意, <code>method</code>和<code>path</code>之间有一个空格,并且破折号分隔<code>path</code>和<code>ip</code>被两侧的空格包围。您可以使用<code>req.method</code> , <code>req.path</code>和<code>req.ip</code>从请求对象获取请求方法(http谓词),相对路由路径和调用者的ip。记得在完成后调用<code>next()</code> ,否则你的服务器将永远停留。确保打开“日志”,并查看某些请求到达时会发生什么... <code>0</code>提示:Express按照它们在代码中出现的顺序评估函数。中间件也是如此。如果您希望它适用于所有路由,则应在它们之前安装它。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 根级别记录器中间件应该是活动的
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/_api/root-middleware-logger'').then(data => { assert.isTrue(data.passed, ''root-level logger is not working as expected''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bed
|
||||
title: Meet the Node console
|
||||
localeTitle: 认识节点控制台
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>在开发过程中,能够检查代码中发生的情况非常重要。 Node只是一个JavaScript环境。与客户端JavaScript一样,您可以使用控制台显示有用的调试信息。在本地计算机上,您将在终端中看到控制台输出。在Glitch上,您可以打开屏幕下方的日志。您可以使用“日志”按钮切换日志面板(左上角,在应用名称下)。 <code>0</code>要开始使用,只需在控制台中打印经典的“Hello World”即可。我们建议在应对这些挑战时保持日志面板处于打开状态。阅读日志,您可以了解可能发生的错误的性质。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'> <code>0</code>修改<code>myApp.js</code>文件以将“Hello World”记录到控制台。
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: <code>"Hello World"</code>应该在控制台中
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/_api/hello-console'').then(data => { assert.isTrue(data.passed, ''"Hello World" is not in the server console''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bef
|
||||
title: Serve an HTML File
|
||||
localeTitle: 提供HTML文件
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>我们可以使用<code>res.sendFile(path)</code>方法响应文件。 <code>0</code>您可以将它放在<code>app.get('/', ...)</code>路由处理程序中。在幕后,此方法将根据其类型设置适当的标头,以指示您的浏览器如何处理您要发送的文件。然后它将读取并发送文件。此方法需要绝对文件路径。我们建议您使用Node全局变量<code>__dirname</code>来计算路径。 <code>0</code>例如<code>absolutePath = __dirname + relativePath/file.ext</code> 。 <code>0</code>要发送的文件是<code>/views/index.html</code> 。尝试“显示”你的应用程序,你应该看到一个很大的HTML标题(以及我们稍后将使用的表单......),没有应用任何样式。 <code>0</code>注意:您可以编辑上一个挑战的解决方案,也可以创建一个新挑战。如果您创建新解决方案,请记住Express会从上到下评估路由。它执行第一个匹配的处理程序。您必须注释掉前面的解决方案,否则服务器将继续使用字符串进行响应。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 您的应用应该提供文件views / index.html
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'')).then(data => { assert.match(data, /<h1>.*<\/h1>/, ''Your app does not serve the expected HTML''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf1
|
||||
title: Serve JSON on a Specific Route
|
||||
localeTitle: 在特定路线上提供JSON
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>虽然HTML服务器提供(您猜对了!)HTML,但API提供数据。 <dfn>REST</dfn> (REpresentational State Transfer)API允许以简单的方式进行数据交换,而无需客户端知道有关服务器的任何细节。客户端只需要知道资源的位置(URL),以及它想要对其执行的操作(动词)。当您获取某些信息而不修改任何信息时,将使用GET动词。目前,用于在Web上移动信息的首选数据格式是JSON。简单地说,JSON是一种将JavaScript对象表示为字符串的便捷方式,因此可以轻松传输。 <code>0</code>让我们通过在路径<code>/json</code>处创建一个以JSON响应的路由来创建一个简单的API。您可以像往常一样使用<code>app.get()</code>方法执行此操作。在路由处理程序内部使用方法<code>res.json()</code> ,将对象作为参数传入。此方法关闭请求 - 响应循环,返回数据。在幕后,它将有效的JavaScript对象转换为字符串,然后设置相应的标题以告诉您的浏览器您正在提供JSON,并将数据发回。有效对象具有通常的结构<code>{key: data}</code> 。数据可以是数字,字符串,嵌套对象或数组。数据也可以是变量或函数调用的结果,在这种情况下,它将在转换为字符串之前进行评估。 <code>0</code>将对象<code>{"message": "Hello json"}</code>作为JSON格式的响应提供给对路由<code>/json</code>的GET请求。然后将浏览器指向your-app-url / json,您应该在屏幕上看到该消息。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 'endpoint <code>/json</code>应该服务于json对象<code>{"message": "Hello json"}</code> '
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/json'').then(data => { assert.equal(data.message, ''Hello json'', ''The \''/json\'' endpoint does not serve the right data''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bf0
|
||||
title: Serve Static Assets
|
||||
localeTitle: 服务静态资产
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
HTML服务器通常有一个或多个用户可以访问的目录。您可以放置应用程序所需的静态资产(样式表,脚本,图像)。在Express中,您可以使用中间件<code>express.static(path)</code>来实现此功能,其中参数是包含资产的文件夹的绝对路径。如果您不知道中间件是什么,请不要担心。我们稍后会详细讨论它。基本上,中间件是拦截路由处理程序,添加某种信息的函数。需要使用<code>app.use(path, middlewareFunction)</code>方法<code>app.use(path, middlewareFunction)</code> 。第一个路径参数是可选的。如果您没有通过它,将为所有请求执行中间件。 <code>0</code>使用<code>app.use()</code>为所有请求安装<code>express.static()</code>中间件。 assets文件夹的绝对路径是<code>__dirname + /public</code> 。 <code>0</code>现在,您的应用应该能够提供CSS样式表。从公共文件夹外部将显示挂载到根目录。你的头版现在应该看起来好一点!
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 您的应用应该从<code>/public</code>目录提供资产文件
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/style.css'').then(data => { assert.match(data, /body\s*\{[^\}]*\}/, ''Your app does not serve static assets''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 587d7fb0367417b2b2512bee
|
||||
title: Start a Working Express Server
|
||||
localeTitle: 启动Working Express服务器
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>在myApp.js文件的前两行中,您可以看到如何轻松创建Express应用程序对象。这个对象有几种方法,我们将在这些挑战中学到很多方法。一个基本方法是<code>app.listen(port)</code> 。它告诉您的服务器侦听给定端口,使其处于运行状态。您可以在文件底部看到它。这是内部评论,因为出于测试原因,我们需要应用程序在后台运行。您可能想要添加的所有代码都介于这两个基本部分之间。 Glitch将端口号存储在环境变量<code>process.env.PORT</code> 。它的价值是<code>3000</code> 。 <code>0</code>让我们的第一个字符串!在Express中,路由采用以下结构: <code>app.METHOD(PATH, HANDLER)</code> 。 METHOD是小写的http方法。 PATH是服务器上的相对路径(它可以是字符串,甚至是正则表达式)。 HANDLER是Express匹配路由时调用的功能。 <code>0</code>处理程序采用表单<code>function(req, res) {...}</code> ,其中req是请求对象,res是响应对象。例如,处理程序
|
||||
<blockquote>function(req, res) {<br> res.send('Response String');<br>}</blockquote> <code>0</code>将提供字符串'Response String'。 <code>0</code>使用<code>app.get()</code>方法为字符串Hello Express提供服务,以匹配/ root路径的GET请求。通过查看日志确保您的代码正常工作,然后在浏览器中查看结果,单击Glitch UI中的“Show Live”按钮。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 您的应用应该提供字符串'Hello Express'
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'')).then(data => { assert.equal(data, ''Hello Express'', ''Your app does not serve the text "Hello Express"''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
---
|
||||
id: 587d7fb2367417b2b2512bf7
|
||||
title: Use body-parser to Parse POST Requests
|
||||
localeTitle: 使用body-parser来解析POST请求
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'> <code>0</code>除了GET之外还有另一个常见的http动词,它是POST。 POST是用于使用HTML表单发送客户端数据的默认方法。在REST约定中,POST用于发送数据以在数据库中创建新项目(新用户或新博客文章)。我们在这个项目中没有数据库,但我们将学习如何处理POST请求。 <code>0</code>在这些请求中,数据不会出现在URL中,它隐藏在请求正文中。这是HTML请求的一部分,也称为有效负载。由于HTML是基于文本的,即使您没有看到数据,也不意味着它们是秘密的。 HTTP POST请求的原始内容如下所示:
|
||||
<blockquote>POST /path/subpath HTTP/1.0<br>From: john@example.com<br>User-Agent: someBrowser/1.0<br>Content-Type: application/x-www-form-urlencoded<br>Content-Length: 20<br>name=John+Doe&age=25</blockquote> <code>0</code>正如您所见,正文被编码为查询字符串。这是HTML表单使用的默认格式。使用Ajax,我们还可以使用JSON来处理具有更复杂结构的数据。还有另一种编码类型:multipart / form-data。这个用于上传二进制文件。 <code>0</code>在本练习中,我们将使用urlencoded主体。 <code>0</code>要解析来自POST请求的数据,您必须安装一个包:body-parser。该软件包允许您使用一系列中间件,这些中间件可以解码不同格式的数据。请参阅<a href="https://github.com/expressjs/body-parser" target="_blank" >此处</a>的文档。 <code>0</code>在package.json中安装body-parser模块。然后在文件的顶部需要它。将其存储在名为bodyParser的变量中。
|
||||
<code>bodyParser.urlencoded({extended: false})</code>返回处理url编码数据的中间件。 <code>extended=false</code>是一个配置选项,告诉解析器使用经典编码。使用它时,值可以只是字符串或数组。扩展版本允许更多的数据灵活性,但它被JSON击败。将<code>app.use()</code>传递给前一个方法调用返回的函数。像往常一样,必须在需要它的所有路由之前安装中间件。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 应该安装'body-parser'中间件
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/_api/add-body-parser'').then(data => { assert.isAbove(data.mountedAt, 0, ''"body-parser" is not mounted correctly'') }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 587d7fb1367417b2b2512bf2
|
||||
title: Use the .env File
|
||||
localeTitle: 使用.env文件
|
||||
challengeType: 2
|
||||
---
|
||||
|
||||
## Description
|
||||
<section id='description'>
|
||||
<code>.env</code>文件是一个隐藏文件,用于将环境变量传递给应用程序。这个文件是秘密的,没有人可以访问它,它可以用来存储你想保密或隐藏的数据。例如,您可以存储来自外部服务或数据库URI的API密钥。您还可以使用它来存储配置选项。通过设置配置选项,您可以更改应用程序的行为,而无需重写某些代码。 <code>0</code>可以从应用程序访问环境变量<code>process.env.VAR_NAME</code> 。 <code>process.env</code>对象是一个全局Node对象,变量作为字符串传递。按照惯例,变量名都是大写的,单词用下划线分隔。 <code>.env</code>是一个shell文件,因此您不需要在引号中包装名称或值。同样重要的是要注意,当您为变量赋值时,等号周围不能有空格,例如<code>VAR_NAME=value</code> 。通常,您将每个变量定义放在单独的行上。 <code>0</code>让我们添加一个环境变量作为配置选项。将变量<code>MESSAGE_STYLE=uppercase</code>存储在<code>.env</code>文件中。然后告诉您在上一次质询中创建的GET <code>/json</code>路由处理程序,如果<code>process.env.MESSAGE_STYLE</code>等于<code>uppercase</code>则将响应对象的消息转换为<code>uppercase</code> 。响应对象应该成为<code>{"message": "HELLO JSON"}</code> 。
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
<section id='instructions'>
|
||||
|
||||
</section>
|
||||
|
||||
## Tests
|
||||
<section id='tests'>
|
||||
|
||||
```yml
|
||||
tests:
|
||||
- text: 端点<code>/json</code>的响应应根据环境变量<code>MESSAGE_STYLE</code>
|
||||
testString: 'getUserInput => $.get(getUserInput(''url'') + ''/_api/use-env-vars'').then(data => { assert.isTrue(data.passed, ''The response of "/json" does not change according to MESSAGE_STYLE''); }, xhr => { throw new Error(xhr.responseText); })'
|
||||
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Challenge Seed
|
||||
<section id='challengeSeed'>
|
||||
|
||||
</section>
|
||||
|
||||
## Solution
|
||||
<section id='solution'>
|
||||
|
||||
```js
|
||||
// solution required
|
||||
```
|
||||
</section>
|
||||
Reference in New Issue
Block a user