ExpressJS 高级教程(六)

原文:Pro Express.js

协议:CC BY-NC-SA 4.0

二十三、附录 A:相关阅读和资源

这个简短的附录提供了几个最有用的 Node.js 资源,供进一步学习使用:

  • 其他 Node.js 框架
  • Node.js 书籍
  • JavaScript 经典

其他 Node.js 框架

毫无疑问,Express.js 框架是 Node.js web 服务中最成熟、最流行、最健壮、经过测试和使用最多的项目。截至本文撰写之时,Express.js 也是来自 NPM 社区的明星数量最多的 NPM 知识库,如图图 A-1 所示。依赖 Express.js 2.x 和 3.x 的真实制作 app 有很多,包括 Storify 1 (被 LiveFyre 2 收购)、DocuSign、 3 新 MySpace、 4 LearnBoost、 5 Geeklist、6 10

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 A-1 。Express.js 是最受欢迎的 NPM 知识库

尽管如此,Express.js 还有很多可供选择的 Node.js 框架。为了帮助开发人员浏览众多选项,我创建了一个类似于 TodoMVC 集合(http://todomvc.com):Node 框架(http://nodeframework.com),其 MVC 框架页面如图图 A-2 所示。顺便说一下,一些更全面的框架依赖于 Express.js(例如,SailsJS 11 ),所以您开始了解 Express.js 是件好事!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 A-2 。Node Frameworks 提供了 Node.js 框架及其统计信息的列表

Node.js 书籍

有关 Node.js 堆栈的其他组件(如数据库和 WebSockets)的更多核心概述和/或信息,请参考以下资源:

  • Azat Mardan (Apress,2014 年)的《实用 Node.js:构建真实世界的可扩展 web 应用》:这是一个循序渐进的指南,帮助您学习如何构建可扩展的真实世界的 web 应用,从安装 Express.js 到编写全栈 Web 应用。
  • JS 快速原型:敏捷 JavaScript 开发12(Azat Mardan,2013):一本关于 Node.js、MongoDB 和 Backbone.js 的初级到中级书籍
  • JavaScript 和 Node 基础知识:基本知识集锦13(Azat Mardan,2014):关于浏览器 JS 和 Node 的简单但重要的概念的简短阅读。
  • 用 Node.js 介绍 OAuth:Twitter API OAuth 1.0,OAuth2.0,OAuth Echo,Everyauth 和 OAuth 2.0 服务器示例14(Azat Mardan,2014):一本关于不同 OAuth 场景的迷你书。
  • Colin J. Ihrig (Apress,2013 年)为开发人员编写的 Pro Node.js):这是一本关于 Node.js 的综合性低级书籍,没有任何非核心模块。
  • Node.js in Action ,作者 Mike Cantelon 等人(Manning Publications,2013):一本由多位作者撰写的关于 Express.js 和其他主题的书。
  • 学习 Node,作者 Shelley Powers (O’Reilly Media,2012):涵盖了 Express、MongoDB、Mongoose 和 Socket.IO。
  • Node 食谱,作者 David Mark Clements(Packt Publishing,2012):涵盖了数据库和 WebSockets。
  • Node:启动并运行,作者汤姆·休斯-克劳奇和迈克·沃森(O’Reilly Media,2012):Node . js 的简要概述
  • Smashing node . js:JavaScript Everywhere,作者 Guillermo Rauch (Wiley,2012):涵盖了 Express.js、Jade 和 Stylus,作者是 Mongoose ORM for MongoDB 的创建者。

JavaScript 经典

要想更深入地了解 JavaScript 这种最容易被误解也是最流行的编程语言,请务必阅读以下经典著作:

  • 雄辩的 JavaScript,第二版,作者 Marijn Haverbeke(无淀粉出版社,2014):JavaScript 编码中的编程基础。
  • 道格拉斯·克洛克福特(O’Reilly Media,2008 年)的《JavaScript:好的部分》(The Good Parts )讲述了 JavaScript 语言中棘手的部分。

课程

如果你喜欢这本书,那么可以看看 Azat 的 Node.js 课程:Node Program ( http://nodeprogram.com)和 Mongoose 课程(http://mongoosecourse.com)。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

二十四、附录 B:将 Express.js 3.x 迁移到 4.x:中间件、路由和其他变化

Express.js 4 ( http://expressjs.com)是针对 web 应用、服务和 API 的最流行、最成熟、最健壮的 Node.js 框架的最新(截至 2014 年 5 月)主要版本。在从 3.x 到 4.x 的过渡中有一些突破性的变化,因此本附录作为一个简短的迁移指南,包括以下内容:

  • 在 Express.js 4 中引入非捆绑中间件
  • 从 Express.js 4 应用中删除不推荐使用的方法
  • Express.js 4 的其他更改
  • 探索新的 Express.js 4 路由实例以及如何链接它
  • 更多 Express.js 4 迁移阅读链接

即使您不打算使用版本 3,本指南也可能对您有用,因为它阐明了从 Express 3 到 4 进行更改的基本原理,以及这些更改背后的哲学。

在 Express.js 4 中引入非捆绑中间件

让我们从最大的改变开始,这个改变将打破你的大多数 Express.js 3.x 项目。这也是讨论最多的(也是期待已久的?)网上的 Express.js 新闻。是的,它是非捆绑的中间件。

就我个人而言,我不确定这是好消息还是坏消息,因为我喜欢不必声明额外的依赖项。然而,我也看到了支持非绑定的理由,包括好处,比如保持 Express.js 模块小,独立升级中间件包,等等。

那么,什么是非捆绑中间件呢?还记得我们能够简单地通过键入app.use(express.middlwarename())来使用的神奇中间件吗?嗯,它们来自于Connect库,但现在它们不再是 Express.js 的一部分。例如,习惯上用 Express.js 3.x 编写app.use(express.cookieParser())。这些模块对于几乎任何 web 应用都是必不可少的。它们是Connect库的一部分,但是 Express.js 4.x 没有Connect作为依赖项。这意味着,如果我们想使用中间件(我们确实这么做了!),我们需要明确地包含中间件,就像这样:

$ npm install body-parse@1.0.2 --save

然后,在 Express.js 主配置文件(如app.js)中,我们这样使用包含的模块:

var bodyParser = require('body-parse')
// ... other dependencies
app.use(bodyParser())
// ... some other Express.js app configuration

表 B-1 描述了开发人员将不得不替换的非捆绑中间件:除了静态之外的所有中间件。没错,静电被遗漏了(为了方便?).下表列出了 Express.js 3.x 中间件名称及其在 Express.js 4.x 中的 NPM 模块对应项。

表 B-1 。中间件比较

|

Express.js 3.x

|

Express.js 4.x

|

github link(github 链接)

|
| — | — | — |
| express.bodyParser | body-parser | https://github.com/expressjs/body-parser |
| express.compress | compression | https://github.com/expressjs/compression |
| express.timeout | connect-timeout | https://github.com/expressjs/timeout |
| express.cookieParser | cookie-parser | https://github.com/expressjs/cookie-parser |
| express.cookieSession | cookie-session | https://github.com/expressjs/cookie-session |
| express.csrf | csurf | https://github.com/expressjs/csurf |
| express.error-handler | errorhandler | https://github.com/expressjs/errorhandler |
| express.session | express-session | https://github.com/expressjs/session |
| express.method-override | method-override | https://github.com/expressjs/method-override |
| express.logger | morgan | https://github.com/expressjs/morgan |
| express.response-time | response-time | https://github.com/expressjs/response-time |
| express.favicon | serve-favicon | https://github.com/expressjs/serve-favicon |
| express.directory | serve-index | https://github.com/expressjs/serve-index |
| express.static | serve-static | https://github.com/expressjs/serve-static |
| express.vhost | vhost | https://github.com/expressjs/vhost |

让事情变得更复杂的是,Express.js/Connect 团队放弃了对表 B-2 中所示模块的支持,并建议您使用替代方案:

表 B-2 。丢弃模块及其替代品

|

丢弃的模块

|

可供选择的事物

|
| — | — |
| cookieParser | cookieskeygrip |
| limit | 生体 |
| multipart | connect-multipartyconnect-busboy |
| query | qs |
| staticCache | stconnect-static |

这些未捆绑的 Express.js/Connect 模块很多都需要维护者1;这是您在 Node.js 领域取得进展的机会!

从 Express.js 4 应用中删除不推荐使用的方法

本节讨论那些不推荐使用的方法以及如何替换它们。

app.configure()

大多数人可能从来没有使用过app.configure(),这是一个很好但不重要的方法,主要用于设置环境。如果你用过,就把app.configure('name', function(){...})换成if (process.env.NODE_ENV === 'name') {...}。例如,这个旧的 Express.js 3 生产配置

app.configure('production', function() {
  app.set('port', 80)
})

在 Express.js 4.x 中变成以下内容:

if (process.env.NODE_ENV === 'production') {
  app.set('port', 80)
}

app .路由

Express.js 4 的一个好的变化是它不再需要编写app.router!所以现在,基本上,中间件和路由的顺序是唯一重要的事情,而在 Express.js 3x 中,开发人员可以通过将app.router放在中间的某个位置来增加执行的顺序。

如果您有任何应该在路由之后订购的中间件,那么将它移动到路由之后的*,按照您想要的顺序。*

例如,在 Express.js 3.x 配置中的路由之后执行的错误处理中间件:

app.use(express.cookieParser())
app.use(app.router)
app.use(express.errorHandler())
app.get('/', routes.index)
app.post('/signup', routes.signup)

在 Express.js 4.x 中迁移到以下代码:

var cookieParse = require('cookie-parser')
var errorHandler = require('errorhandler')
...
app.use(cookieParser())
app.get('/', routes.index)
app.post('/signup', routes.signup)
app.use(errorHandler())

换句话说,app.use()和带动词的路线,如app.get()app.post()app.put()app.del()成了对等物。

res.on(“标题”)

从 Connect 3 中移除了res.on('header')事件。

res.charset

在 Express.js 4.x 中,用res.type()res.set('content-type')代替 Express.js 3.x 中的res.charset

利斯特 headersent

在 Express.js 4.x 中,用res.headersSent代替res.headerSent

req.accepted()

在 Express.js 4.x 中,用req.accepts()代替req.accepted()

Express.js 4.x 中的req.accepts由模块accepts ( https://github.com/expressjs/accepts)提供支持,GitHub 文档表明该模块是从 Koa ( http://koajs.com)中提取的,用于一般用途。

Express.js 4 的其他更改

本节介绍了 Express.js 4 的其他一些变化。

app.use()

令人惊讶的是,app.use()现在接受 URL 参数。这是使app.use()和动词 route 方法相等并减少混淆的又一步。参数在req.params对象中。

例如,如果我们需要从 URL 获得一个 ID,在 Express.js 4.x 中间件中我们可以写

app.use('/posts/:slug', function(req, res, next) {
  req.db.findPostBySlug(req.params.slug, function(post){
  ...
  })
})

资源位置()

在 Express.js 4 中,res.location()不再解析相对 URL。

app.route()

参见下一节“探索新的 Express.js 4 Route 实例以及如何链接它”,了解关于 Express.js 4 中app.route()角色的详细信息。

json 空间

在 Express.js 4 中,json spaces在开发中默认是关闭的。

请求参数

req.params是对象,不是数组。

没有.本地

res.locals现在是一个物体。

req.is

Express.js 4.x 中的req.is已经被模块type-is ( https://github.com/expressjs/type-is)所取代,根据 GitHub 文档,该模块也是从 Koa.js ( http://koajs.com)中提取出来用于一般用途。

Express.js 命令行生成器

对于命令行生成器,请使用

$ sudo npm install -g express-generator

而不是普通的老式$ sudo npm install -g express

探索新的 Express.js 4 路由实例以及如何链接它

app.route()方法为我们提供了新的 Express.js 4 route 实例。在探究之前,我们先来看看路由本身。

在 Express.js 4.x 中,Router类得到了增强。在 Express.js 3.x 中,app 实例使用 router,但现在我们可以创建许多 route 实例,并通过附加特定的中间件和其他逻辑将它们用于特定的路径。这可以用来重组代码。

这里有一个开发者如何在 Express.js 4.x 中使用Router的基本例子,假设我们有两个类别的评论:书籍和游戏。审查的逻辑类似于路由,并被打包成路由:

var express = require('express')
var app = express()
var router = express.Router()

router.use(function(req, res, next) {
  //process each request
});

router.get('/', function(req, res, next) {
  // get the home page for that entity
  next();
});

router.get('/reviews', function(req, res, next) {
  // Get the reviews for that entity
  next();
});

app.use('/books', router);
app.use('/games', router);

app.listen(3000);

app.route()router.route()返回新的 Express.js 4.x route 实例,我们可以这样链:

router.route('/post/:slug')
  .all(function(req, res, next) {
    // Runs each time
    // We can fetch the post by id from the database
  })
  .get(function(req, res, next) {
    //Render post
  })
  .put(function(req, res, next) {
    //Update post
  })
  .post(function(req, res, next) {
    //Create new comment
  })
  .del(function(req, res, next) {
    //Remove post
  })

在 Express.js 3.x 中,如果没有路由链,我们将不得不反复输入相同的路径(增加了输入错误的风险):

router.all('/post/:slug', function(req, res, next) {
  // runs each time
  // we can fetch the post by ID from the database
})
router.get('/post/:slug', function(req, res, next) {
  //render post
})
router.put('/post/:slug', function(req, res, next) {
  //update post
})
router.post('/post/:slug', function(req, res, next) {
  //create new comment
})
router.delete('/post/:slug', function(req, res, next) {
  //remove post
})

同一个路由实例也可以有自己的中间件、param 和 HTTP 动词方法(如上所示)。

更多 Express.js 4 迁移阅读链接

所以,总的来说,Express.js 4.x 的变化不是很大,而且迁移可能是一个相对轻松的过程。但是,在您点击$ git checkout -b express4为从 3.x 到 4.x 的迁移创建一个新的 Git 分支express4之前,请仔细考虑您是否真的需要迁移!我知道许多成功的生产应用没有更新它们的主框架版本。在 Storify,我们曾经在 3.x 可用的时候运行 Express.js 2.x,也不是什么大事。作为另一个例子,从 Ruby 世界来看,我知道许多应用和开发人员仍然在使用 Ruby on Rails 2.x,尽管 Ruby on Rails 4.x 已经推出。

如果您决定使用 Express.js 4,不要仅仅依赖这个简单的概述。看看这些额外的资源,帮助您更轻松地从 Express.js 3.x 过渡到 4.x:

  • 官方迁移指南 2
  • Express.js 中的新功能 4 . x3
  • Express.js 4.x 文档 4

Express.js 4、Node.js 和 MongoDB REST API 教程 5


1

2

3

4

5

二十五、附录 C:Express.js 4 备忘单

Pro Express.js 是一本内容丰富的书,有很多例子教你关于中间件、模式和配置的知识。因此,当您开始从事自己的项目时,您会发现拥有最重要的函数和命令的快速参考—备忘单是非常有用的。我已经创建了自己的 Express.js 4 备忘单,如图图 C-1 所示,我将它作为礼物送给 Pro Express.js 的读者。你可以在https://gum.co/NQiQ/AC30238A-5C5C免费下载这份备忘单的精美 PDF 格式,正常价格是 4.99 美元。此链接仅供 Pro Express.js 的读者使用,请勿分享给任何人。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 C-1 。Express.js 4 备忘单

备忘单中的信息可在本附录中找到,也可在线访问https://github.com/azat-co/cheatsheets/blob/master/express4/index.md。备忘单包含以下几个部分:

  • 装置
  • 发电机
  • 基础
  • HTTP 动词和路由
  • 请求
  • 请求标题快捷方式
  • 反应
  • 经手人签名
  • 铁笔和玉石
  • 身体
  • 静态
  • 连接中间件
  • 其他流行的中间件

在撰写本文时,备忘单适用于 Express 4.10.4。

装置

  • 本地安装最新的 Express.js】

  • 本地安装 Express.js v4.2.0,保存到package.json

    $ sudo npm install express@4.2.0 --save
    
    
  • 安装 Express.js 命令行生成器 v4.0.0

    $ sudo npm install -g express-generator@4.0.0
    
    

发电机

用法:$ express [options] [dir]

选项:

  • -h:打印使用信息
  • -V:打印快速生成器版本号
  • -e:增加 ejs 引擎支持,省略默认为 jade
  • -H:增加 hogan.js 引擎支持
  • -c <library>:添加 CSS 支持(less|stylus|compass),如果省略,默认为普通 CSS
  • -f:生成到非空目录

基础

  • 包含模块:

    var express = require('express')
    
    
  • 创建实例:

    var app = express()
    
    
  • 启动 Express.js 服务器:

    app.listen(portNumber, callback)
    
    
  • 启动 Express.js 服务器:

    http.createServer(app).listen(portNumber, callback)
    
    
  • 通过

    app.set(key, value)
    
    

    键设置属性值

  • 通过关键字

    app.get(key)
    
    

    获取属性值

HTTP 动词和路由

  • app.get(urlPattern, requestHandler[, requestHandler2, ...])
  • app.post(urlPattern, requestHandler[, requestHandler2, ...])
  • app.put(urlPattern, requestHandler[, requestHandler2, ...])
  • app.delete(urlPattern, requestHandler[, requestHandler2, ...])
  • app.all(urlPattern, requestHandler[, requestHandler2, ...])
  • app.param([name,] callback):
  • app.use([urlPattern,] requestHandler[, requestHandler2, ...])

请求

  • request.params:参数中间件
  • request.param:提取一个参数
  • request.query:提取查询字符串参数
  • request.route:返回路线字符串
  • request.cookies:cookie,需要cookie-parser
  • request.signedCookies:已签名的 cookies,需要cookie-parser
  • request.body:有效载荷,需要body-parser

请求标题快捷方式

  • request.get(headerKey):表头键值
  • request.accepts(type):检查类型是否被接受
  • request.acceptsLanguage(language):检查语言
  • request.acceptsCharset(charset):检查字符集
  • request.is(type):检查类型
  • request.ip : IP 地址
  • request.ips : IP 地址(打开信任代理)
  • request.pathURL 路径
  • request.host:没有端口号的主机
  • request.fresh:检查新鲜度
  • request.stale:检查陈旧性
  • request.xhr:对于 AJAX-y 请求为真
  • request.protocol:返回 HTTP 协议
  • request.secure:检查协议是否为https
  • request.subdomains:子域数组
  • request.originalUrl原始 URL

反应

  • response.redirect(status, url):重定向请求
  • response.send(status, data):发送响应
  • response.json(status, data):发送 JSON 并强制正确的报头
  • response.sendfile(path, options, callback):发送文件
  • response.render(templateName, locals, callback):渲染模板
  • response.locals:将数据传递给模板

经手人签名

  • function(request, response, next) {}:请求处理者签名
  • function(error, request, response, next) {}:错误处理程序签名

铁笔和玉石

app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'jade')
app.use(require('stylus').middleware(path.join(__dirname, 'public')))

身体

var bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded())

静态

app.use(express.static(path.join(__dirname, 'public')))

连接中间件

$ sudo npm install <package_name> --save

  • body-parser:请求有效载荷
  • compression : Gzip
  • connect-timeout:请求超时,单位为毫秒,默认为 5000
  • cookie-parser:饼干
  • cookie-session:通过 Cookies 存储的会话
  • csurf : CSRF
  • errorhandler:错误处理程序
  • express-session:通过内存或其他存储进行会话
  • method-override : HTTP 方法覆盖
  • morgan:服务器日志
  • response-time:响应时间中间件
  • serve-favicon:收藏夹图标
  • serve-index:提供包含目录列表的页面
  • serve-static:静态内容
  • vhost:虚拟主机

其他流行的中间件

  • cookieskeygrip:类似于cookieParser
  • raw-body:生体
  • connect-multipartyconnect-busboy:连接多方中间件,连接勤杂工中间件
  • qs:类似于query
  • stconnect-static类似于staticCache
  • express-validator:验证
  • less:少 CSS
  • passport:认证库
  • helmet:安全标题
  • connect-cors : 心形
  • connect-redis:连接中继

二十六、附录 D:ExpressWorks

ExpressWorks 是一个自动化的研讨会,它引导您构建 Express.js 服务器,处理 GET、POST 和 PUT 请求,以及提取查询字符串、有效负载和 URL 参数。ExpressWorks 为您提供了任务和提示。你写下这些任务的解决方案。然后,在您将解决方案编写为 Express.js 应用后,ExpressWorks 会验证您对问题的解决方案。

ExpressWorks 以 workshop1为原型,以@substack 3 和@maxogden 为灵感来源于 stream-adventure24 本附录包括以下高速公路简介:

  • 装置
  • 使用
  • 重复定位
  • 任务

装置

ExpressWorks v0.0.23 的建议全局安装如下:

$ npm install -g expressworks@0.0.23
$ expressworks

如果遇到错误,请尝试

$ sudo npm install -g expressworks@0.0.23

另一种方法(对于高级开发人员)是使用本地安装。为此,请在本地运行并安装以下程序:

$ mkdir node_modules
$ npm install expressworks@0.0.23
$ cd node_modules/expressworks$ node expressworks

使用

完成安装后,ExpressWorks 理解这些命令:

  • $ expressworks:显示菜单,交互选择车间。
  • 显示所有车间的换行符列表。
  • $ expressworks select NAME:选择一个车间。
  • $ expressworks current:显示当前选择的车间。
  • $ expressworks run program.js:针对所选输入运行程序。
  • 根据预期的输出来验证你的程序。

重复定位

如果要重置已完成任务列表,如图 D-1 所示,清空~/.config/expressworks/completed.json文件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 D-1 。已完成的任务

任务

本节描述了您将遇到的一些任务。

你好世界

创建一个运行在 l ocalhost:3000上的 Express.js app,输出“Hello World!”有人去 root '/home'的时候。

ExpressWorks 给你提供的process.argv[2],就是端口号。

翡翠

创建一个 Express.js 应用,其主页(/home)由 Jade 模板引擎呈现,显示当前日期(toDateString)。

古老的好形式

编写一个处理 HTML 表单输入(<form><input name="str"/></form>)并反向打印str值的路径('/form')。

静态

将静态中间件应用到没有任何路由的服务器index.html文件。通过路径的process.argv[3]值提供并使用index.html文件。但是,您可以将自己的文件用于此内容:

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="/main.css"/>
  </head>
  <body>
    <p>I am red!</p>
  </body>
</html>

时尚的 CSS

用一些 Stylus 中间件来设计你的 HTML。process.argv[3]中提供了main.styl文件的路径,或者您可以从这些文件/文件夹中创建自己的文件/文件夹:

p
color red

index.html文件如下:

<html>
  <head>
    <title>expressworks</title>
    <link rel="stylesheet" type="text/css" href="/main.css"/>
  </head>
  <body>
    <p>I am red!</p>
  </body>
</html>

帕梅!帕梅!帕梅!帕梅!帕梅!帕梅

创建一个 Express.js 服务器来处理 PUT /message/:id请求(例如,PUT /message/526aa677a8ceb64569c9d4fb)。

该请求的响应返回用日期散列的 id SHA1:

require('crypto')
  .createHash('sha1')
  .update(new Date().toDateString().toString() + id)
  .digest('hex')

查询中有什么

编写一个路由,从 GET /search URL 路由(例如?results=recent&include_tabs=true)中的查询字符串中提取数据,然后转换并以 JSON 格式输出回给用户。

加入我吧

写一个服务器,读取一个文件(文件名传入process.argv[3]),然后解析成 JSON,用res.json(object)把内容输出给用户。

摘要

ExpressWorks 是一个命令行工具,它将帮助您熟悉 Express.js 的一些基础知识。如果您喜欢这种学习方法,请在http://nodeschool.io查看免费提供给您的类似研讨会/工具。


1

2

3

4

第一部分:入门指南

第二部分:深度 API 参考

第三部分:解决常见和抽象的问题

第四部分:教程和示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值