Nginx之URL重写模块 ngx_http_rewrite_module


Rewrite是Nginx服务器提供的一个重要基本功能,是Web服务器产品中几乎必备的功能。 主要的作用是用来实现URL的重写。

注意:Nginx服务器的Rewrite功能的实现依赖于PCRE的支持,因此在编译安装Nginx服务之前,需要安装PCRE库(正则表达式库)。Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置(nginx默认将该模块编译进来)。

地址重写 & 地址转发

重写和转发的区别:

  • 地址重写,浏览器地址会发生变化,而地址转发则不变。

  • 一次地址重写会产生两次请求,而一次地址转发只会产生一次请求。

  • 地址重写到的页面必须是一个完整的路径而地址转发则不需要。

  • 地址重写因为是两次请求所以request范围内属性不能传递给新页面而地址转发因为是一次请求所以可以传递值。

  • 地址转发速度快于地址重写。

一、Rewrite的相关配置指令

(一)set 指令

该指令用来设置一个新的变量

语法set $variable value;
默认值-
位置server、location、if

variable:变量的名称,该变量名称要用“$”作为变量的第一个字符,且不能与Nginx的内置全局变量同名
value:变量的值,可以是字符串,其他变量或者变量的组合等

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/set.conf 
server {
  listen 81;
  server_name localhost;
  
  location /server {
    set $name TOM;
    set $age 18;
    default_type text/plain;
    return 200 $name=$age;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

效果:
在这里插入图片描述

Rewrite常用全局变量

变量说明
$args变量中存放了请求URL中的请求参数。比如 http://192.168.1.10/server?arg1=value1&arg2=value2 中的”arg1=value1&arg2=value2”,功能和$query_string一样
$http_user_agent变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)
$host变量存储的是访问服务器的 server_name 值
$document_uri变量存储的是当前访问地址的URI。比如 http://192.168.1.10/server?id=10&name=zhangsan 中的“/server”,功能和$uri一样
$document_root变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带的html目录所在位置
$content_length变量存储的是请求头中Content-Length的值(头信息的内容长度)
$content_type变量存储的是请求头中的Content-Type的值(mime类型)
$http_cookie变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie 'cookieName=cookieValue’来添加cookie数据
$limit_rate变量中存储的是Nginx服务器对网络连接速率的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制
$remote_addr变量中存储的是客户端的IP地址
$remote_port变量中存储了客户端与服务端建立连接的端口号
$remote_user变量中存储了客户端的用户名,需要有认证模块才能获取
$scheme变量中存储了访问协议
$server_addr服务端的地址
$server_port客户端请求到达服务端的端口号
$server_protocol客户端请求协议的版本,比如"HTTP/1.1"
$request_body_file发给后端服务器的本地文件资源名称
$request_method客户端的请求方式,比如"GET"、"POST"等
$request_uri当前请求的URI,并且携带请求参数,比如 http://192.168.1.10/server?id=10&name=zhangsan 中的"/server?id=10&name=zhangsan";$args 和 $document_uri的结合

上述参数还可以在日志中通过 log_format 指令使用

(二)if 指令

该指令用来支持条件判断,并根据判断结果选择不同的Nginx配置

语法if (condition) {…}
默认值-
位置server、location

condition为判定条件,可以支持以下写法:

  1. 变量名。如果变量名对应的值为空字符串或“0”,if都判断为false,其他条件为true。
if ($param){

}

【例 】

案例一:

[root@nginx ~]# vim /etc/nginx/conf.d/if.conf
server {
  listen 81;
  server_name localhost;

  location /testif {
    set $username '';		# 设置一个变量,变量名为username,值为空
    default_type text/plain;	
    if ($username){			# 因为username变量为空,所以if判断为false
      return 200 $username;	# 判断条件为true,页面上返回该变量的值
    }
    return 200 'param is empty';	# 判断条件为false,页面上返回字符串 “param is empty”
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

效果:
在这里插入图片描述

案例二:

[root@nginx ~]# vim /etc/nginx/conf.d/if.conf 
server {
  listen 81;
  server_name localhost;

  location /testif {
    set $username 'xiaoming';
    default_type text/plain;
    if ($username){
      return 200 $username;
    }
    return 200 'param is empty';
    return 200  $args;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

效果:

在这里插入图片描述
案例三:

[root@nginx ~]# vim /etc/nginx/conf.d/if.conf 
server {
  listen 81;
  server_name localhost;

  location /testif {
    default_type text/plain;
    if ($args){
      return 200 success;
    }
    return 200 error;
  }
}
# 传递参数返回success,没有传递参数返回error

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

效果:
在这里插入图片描述
在这里插入图片描述

  1. 使用“=”和“!=”比较变量和字符串是否相等,满足条件为true,不满足为false

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/if.conf
server {
  listen 81;
  server_name localhost;

  location /testif {
    default_type text/plain;
    if ($args){
      return 200 success;
    }
    if ($request_method = POST){	# 要想执行到第二个if,必须上面的if不满足;即没有传递参数(或参数为0)且客户端请求方式为POST,返回405状态码
      return 405;
    }
    return 200 error;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

效果:

因为没有传递参数且请求方式为GET,所以返回error
在这里插入图片描述因为传递参数,所以返回success
在这里插入图片描述
浏览器不便于直接模拟POST请求,使用命令行模拟;因为不带参数且请求方式为POST,所以返回405
在这里插入图片描述
注意:此处和JAVA不太一样的地方是字符串不需要添加引号,并且等号和不等号前后都需要加空格。

  1. 使用正则表达式对变量进行匹配,匹配成功返回true,否则返回false。变量与正则表达式之间使用 “~” ,"~*","!~","!~*"来连接。

“~” :代表匹配正则表达式过程中区分大小写;
"~*" :代表匹配正则表达式过程中不区分大小写;
"!~“和”!~*": 刚好和上面取相反值,如果匹配上返回false,匹配不上返回true。

注意:正则达式字符串一般不需要加引号,但是字符串中如果包含"}“或者是”;"等字符时,就需要加上引号。

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/if.conf 
server {
  listen 81;
  server_name localhost;

  location /testif {
    default_type text/plain;
    if ($http_user_agent ~* firefox){		# 如果客户端浏览器为火狐,则页面返回字符串“ TRUE:客户端版本具体信息 ”,否则返回 “ FALSE:客户端版本具体信息 ”
      return 200 TRUE:$http_user_agent;
    }
    return 200 FALSE:$http_user_agent;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

IE浏览器测试
在这里插入图片描述火狐浏览器测试

在这里插入图片描述

  1. 判断请求的文件是否存在使用"-f"和"!-f"
if (-f $request_filename){
  ...
}

if (!-f $request_filename){
  ...
}

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/if.conf
server {
  listen 81;
  server_name localhost;

  location / {
    root /usr/share/nginx/html;
    default_type text/html;
    if (!-f $request_filename){
      return 200 '<h1>sorry,file not found</h1>';
    }
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

在这里插入图片描述在这里插入图片描述

  1. 判断请求的目录是否存在使用"-d"和"!-d"
  2. 判断请求的目录或者文件是否存在使用"-e"和"!-e"
  3. 判断请求的文件是否可执行使用"-x"和"!-x"

(三)break 指令

该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。并且break还有另外一个功能就是终止当前的匹配并把当前的URI在本location进行重定向访问处理。

语法break;
默认值-
位置server、location、if

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/break.conf
server {
  listen 82;
  server_name localhost;
  root /usr/share/nginx/html;
  
  location /testbreak {
    default_type text/plain;
    set $username TOM;
    if ($args){
      set $username JERRY;
      break;
      set $username ROSE;
    }
    add_header username $username;	# 将改变量加入到头信息中
    return 200 $username;
  }
}

[root@nginx ~]# mkdir /usr/share/nginx/html/testbreak
[root@nginx ~]# echo "testbreak/index.html" >  /usr/share/nginx/html/testbreak/index.html

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

结果:

没有传递参数,所以没有进入if条件,那么输出结果为TOM
在这里插入图片描述任意传递参数后,因为进入if条件中,所以此时username为JERRY且有break所以后面的ROSE并不会赋值给变量username。
可以看到,break先是实现了301永久跳转
在这里插入图片描述

(四)return 指令

该指令用于完成对请求的处理,直接向客户端返回。在return后的所有Nginx配置都是无效的。

语法return code [text];
return code URL;
return URL;
默认值-
位置server、location、if

code:为返回客户端的HTTP状态代理。可以返回的状态码为0~999的任意HTTP状态代理
text:为返回给客户端的响应体内容,支持变量的使用
URL:为返回给客户端的URL的值

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/testreturn.conf
server {
  listen 82;
  server_name localhost;

  location /testreturn1 {
    return 502;
  }

  location /testreturn2 {
    default_type text/plain;
    return 200 'It is a test';
  }

  location /testreturn3 {
    default_type text/html;
    return 200 '<h1>It is a test</h1>';
  }

  location /testreturn4 {
    default_type application/json;
    return 200 '{id:1,name:"zhangsan"}';
  }

  location /testreturn5 {
    return https://www.baidu.com;
  }
}

测试:
在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

(五)rewrite 指令

该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。

语法rewrite regex replacement [flag]
默认值-
位置server、location、if

regex:用来匹配URI的正则表达式
replacement:匹配成功后,用于替换URI中被截取内容的字符串。 如果该字符串是以”http://“或”https://“开头的,则不会继续向下对URI进行其他处理,而是直接返回重写后的URI给客户端。

【例 】

[root@nginx ~]# vim /etc/nginx/conf.d/rewrite.conf
server {
  listen 82;
  server_name localhost;

  location /rewrite {
    rewrite ^/rewrite/url\w*$ https://www.baidu.com;
    rewrite ^/rewrite/(test)\w*$ /$1;
    rewrite ^/rewrite/(demo)\w*$ /$1;
  }

  location /test{
    default_type text/plain;
    return 200 test;
  }

  location /demo{
    default_type text/plain;
    return 200 demo;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

测试;

第一个rewrite指令效果
在这里插入图片描述第二个rewrite指令效果
在这里插入图片描述

第三个rewrite指令效果
在这里插入图片描述
flag:用来设置rewrite对URI的处理行为,可选值如下:

  • last:终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用各location块进行处理。该标志将重写后的URI重写在server块中执行,为重写后的URI提供了转入到其他location块的机会。
[root@nginx ~]# vim /etc/nginx/conf.d/rewrite.conf
server {
  listen 82;
  server_name localhost;

  location /rewrite {
    rewrite ^/rewrite/(testlast)\w*$ /$1 last;	# 访问 192.168.126.41:82/rewrite/testlastxxxx 那么会转发到其他匹配/testlast的location去处理
  }

  location /testlast{	
    default_type text/plain;
    return 200 test;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

在这里插入图片描述

  • break:将此处重写的URI作为一个新的URI,在本块中继续进行处理。该标志将重写后的地址在当前的location块中执行,不会将新的URI转向其他的location块。
[root@nginx ~]# vim /etc/nginx/conf.d/rewrite.conf
server {
  listen 82;
  server_name localhost;

  location /rewrite {
    rewrite ^/rewrite/(testbreak)\w*$ /$1 break;	# 访问 192.168.126.41:82/rewrite/testlastxxxx 那么会在本location块中进行处理
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

因为在该location块中未指明该文件的位置,默认去安装目录下也没有此文件
在这里插入图片描述

  • redirect:将重写后的URI返回给客户端,状态码为302,指明是临时重定向URI,主要用在replacement变量不是以”http://“或”https://“开头的情况。
[root@nginx ~]# vim /etc/nginx/conf.d/rewrite.conf
server {
  listen 82;
  server_name localhost;

  location /rewrite {
    rewrite ^/rewrite/(testredirect)\w*$ /$1 redirect;	# 访问 192.168.126.41:82/rewrite/testlastxxxx 那么会在本location块中进行处理
  }
  location /testredirect{	
    default_type text/plain;
    return 200 testdirect;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

在浏览器输入 192.168.126.41:81/rewrite/testredirectabcdefg 后会被临时重定向,所以浏览器URL栏显示为 192.168.126.41:81/testredirect
在这里插入图片描述

  • permanent:将重写后的URI返回给客户端,状态码为301,指明时永久重定向URI,主要用在replacement变量不是以”http://“或”https://“开头的情况。
[root@nginx ~]# vim /etc/nginx/conf.d/rewrite.conf
server {
  listen 82;
  server_name localhost;

  location /rewrite {
    rewrite ^/rewrite/(testpermanent)\w*$ /$1 permanent;
  }

  location /testpermanent{
    default_type text/plain;
    return 200 testpermanent;
  }
}

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

在浏览器输入 192.168.126.41:81/rewrite/testpermanentabcde 后会被永久重定向,所以浏览器URL栏显示为 192.168.126.41:81/testpermanent

在这里插入图片描述

(六)rewrite_log 指令

该指令配置是否开启URL重写日志的输出功能

语法rewrite_log on|off
默认值rewrite_log off
位置http、server、location、if

开启后,URL重写的相关日志将以notice级别输出到err_log指令配置的日志文件汇总。

rewrite_log on;
error_log /path/to/error.log notice;

二、Rewrite的应用场景

(一)域名跳转

当输入 www.jd.com ,便可以访问京东网站,同样也可以输入 www.360buy.com 同样访问到京东网站。京东刚开始的时候域名就是 www.360buy.com ,后面由于某些原因将域名更换为 www.jd.com 。虽然说域名改变了,但是对于以前只记住 www.360buy.com 域名的用户来说,如何将这部分用户也迁移到 www.jd.com 新域名上来。此时,就可以使用Nginx中Rewrite的域名跳转功能来实现。

【例 】

三个域名

在这里插入图片描述

[root@nginx ~]# vim /etc/nginx/conf.d/hosts.conf
server {
  listen 80;
  server_name www.test.com;

  location / {
    default_type text/html;
    return 200 '<h1>It is test!';
  }
}

server {
  listen 80;
  server_name www.test1.com www.test2.cn;
  rewrite ^/ http://www.test.com;
}

效果:
在这里插入图片描述

在这里插入图片描述

但是这样跳转也存在一定的问题,比如,访问 www.test1.com/user/login 会跳转到 www.test.com 而不会跳转到 www.test.com/user/login ,所以,需要对rewrite指令中的regex(regex:用来匹配URI的正则表达式)做进一步处理。

[root@nginx ~]# vim /etc/nginx/conf.d/hosts.conf
server {
  listen 80;
  server_name www.test.com;

  location / {
    default_type text/html;
    return 200 '<h1>It is test!';
  }
}

server {
  listen 80;
  server_name www.test1.com www.test2.cn;
  rewrite ^(.*) http://www.test.com$1;
}

那么,此时如果访问 www.test1.com/user/login 或 www.test2.cn/user/login 会跳转到 www.test.com/user/login

在这里插入图片描述

(二)域名镜像

镜像网站指定是将一个完全相同的网站分别放置到几台服务器上,并分别使用独立的URL进行访问。其中一台服务器上的网站叫主站,其他的为镜像网站。镜像网站和主站没有太大的区别,可以把镜像网站理解为主站的一个备份节点。可以通过镜像网站提供网站在不同地区的响应速度。镜像网站可以平衡网站的流量负载、可以解决网络宽带限制、封锁等。

当web项目开发完成以后,会将它部署在一台服务器上对外提供服务,如果使用的是单节点的方式对外提供服务就会存在一些缺点。比如:高可用性较差(该节点出现故障,整个web项目都无法对外界提供服务)、无法应对比较高的并发量等。为了解决这些问题比较常见的做法是通过集群(搭建多个节点提供服务)方式来部署web项目在多个节点上,那这个时候其中一台节点就称为主站,其他的节点可以称为镜像网站(镜像网站也可以理解为主站的备份节点,那么就提高了高可用性,其中一台节点挂掉,其他的节点可以正常对外提供服务)。主站和镜像网站节点中的内容应该是一样的,提供相同的服务。并且还可以将这些节点分布在不同的地区同时提高不同地区的响应速度,同时,可以将用户的请求分发在不同的节点上,实现网站的流量负载。当然还可以为每一个web节点提供一个域名,这样加入其中一个域名被限制,那么另外几台web节点还是能通过其他域名正常访问。

而我们所说的域名镜像和网站镜像比较类似,上述案例中,将 www.test1.com 和 www.test2.cn 都能跳转到 www.test.com,那么 www.test.com 我们就可以把它起名叫主域名,其他两个就是我们所说的镜像域名,当然如果我们不想把整个网站做镜像,只想为其中某一个子目录下的资源做镜像,我们可以在location块中配置rewrite功能,比如:

# 比如,只想针对user功能模块做镜像,即访问www.test1.com 或 www.test2.cn 域名下的user资源时,不进行跳转,访问其他资源时跳转到www.test.com来

[root@nginx ~]# vim /etc/nginx/conf.d/hosts.conf
server {
  listen 80;
  server_name www.test.com;

  location / {
    default_type text/html;
    return 200 '<h1>It is test!';
  }
}

server {
  listen 80;
  server_name www.test1.com www.test2.cn;
 #rewrite ^(.*) http://www.test.com$1;

  location /user {
    rewrite ^(/user)(.*)$ http://www.test1.com$1$2;
  }
}

(三)独立域名

一个完整的项目包含多个模块,比如购物网站有商品搜索模块、商品详情模块和购物车模块等,如何为每一个模块设置独立的域名。

需求:

http://search.test.com:81  访问商品搜索模块
http://item.test.com:82	  访问商品详情模块
http://cart.test.com:83	  访问商品购物车模块
server{
	listen 81;
	server_name test.com;
	rewrite ^(.*) http://www.test.com/search$1;
}
server{
	listen 82;
	server_name item.test.com;
	rewrite ^(.*) http://www.test.com/item$1;
}
server{
	listen 83;
	server_name cart.test.com;
	rewrite ^(.*) http://www.test.com/cart$1;
}

(四)合并目录

搜索引擎优化(SEO)是一种利用搜索引擎的搜索规则来提高目的网站在有关搜索引擎内排名的方式。我们在创建自己的站点时,可以通过很多中方式来有效的提供搜索引擎优化的程度。其中有一项就包含URL的目录层级一般不要超过三层,否则的话不利于搜索引擎的搜索也给客户端的输入带来了负担,但是将所有的文件放在一个目录下又会导致文件资源管理混乱并且访问文件的速度也会随着文件增多而慢下来,这两个问题是相互矛盾的,使用rewrite如何解决上述问题。

比如:

网站中有一个资源文件的访问路径时 /server/11/22/33/44/20.html,也就是说20.html存在于第5级目录下,如果想要访问该资源文件,客户端的URL地址就要写成 http://IP:PORT/server/11/22/33/44/20.html。

[root@nginx ~]# vim /etc/nginx/conf.d/test.conf
server {
  listen 8082;
  server_name localhost;

  location /server {
    root /myweb;
    index index.html;
  }
}

[root@nginx ~]# mkdir -p /myweb/server/11/22/33/44/
[root@nginx ~]# echo "<h1> server! </h1>" > /myweb/server/11/22/33/44/20.html
[root@nginx ~]# tree /myweb/server/
/myweb/server/
└── 11
    └── 22
        └── 33
            └── 44
                └── 20.html

4 directories, 1 file

[root@nginx ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

访问
在这里插入图片描述
但是这个时非常不利于SEO搜索引擎优化的,同时客户端也不好记。使用rewrite指令进行如下配置:

[root@nginx ~]# vim /etc/nginx/conf.d/test.conf
server {
  listen 8082;
  server_name localhost;

  location /server {
    root /myweb;
    index index.html;
    rewrite ^/server-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+).html$ /server/$1/$2/$3/$4/$5.html last;
  }
}

[root@nginx ~]# nginx -s reload

访问
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值