如今随着大量的应用转移到网络,作为开发者,会经常做一些通讯测试,例如从网站获取信息、模拟用户向网站提交或者上传数据,查看应用通讯情况等等,现在变成了非常重要的任务。

一起来认识 cURL

cURL 是一个非常有用的工具,能够进行各种 URL 操作和数据的传输,通过它发出网络请求,然后得到和提取数据,显示在"标准输出"(stdout)上面。

本文只关注如何进行 HTTP 请求,如果你有对 cURL 进行更深入了解的想法的话,可以使用下面的命令:curl –help 或 curl –manual,或者参阅 cURL 的官方文档中心[1]。

cURL 的安装

目前主流的操作系统都已经内置了 cURL 命令,无需额外安装。如果有需要,可以参考以下文档。

  • cURL 下载中心[2]
  • Windows 安装[3]
  • Linux 安装[4]

cURL 查看网页源码

直接在 cURL 命令后加上网址,就可以看到网页源码。我们以网址 http://upyun.com 为例(选择该网址,主要因为它的网页代码较短):

mark@Mark-Li:~$ curl upyun.com

<html>
<head><title> Found</title></head>
<body bgcolor="white">
<center><h1> Found</h1></center>
<hr><center>openresty/1.13.6.2</center>
</body>
</html>

默认 cURL 会把结果输出到 STDOUT,可以使用 -o,-o 或 重定向 将返回结果保存到文件中:

curl -o [文件名] upyun.com
curl -O [文件保存路径] upyun.com
curl upyun.com > upyun.html mark@Mark-Li:~$ curl -o upyun.html upyun.com
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
:: :: --:--:--
mark@Mark-Li:~$ ls
upyun.html

HTTP 协议

HTTP 协议 用于从 WEB 服务器上读取数据,它是基于 TCP/IP 协议上的一个简单的协议。该协议同时也能够让你通过使用一些不同的方法向服务器提交数据。

HTTP 协议是向服务器发送的要进行一个特殊操作的 ACSII 文本,随后在要求的内容发送给客户端之前,服务器会向客户端发送几行回应的数据。

客户端 cURL 向服务器发送一项请求,请求通常包括 方法(比如 GET、POST、HEAD 等等)、一些 请求头、有时还有 请求正文。接到请求后,服务器返回 状态行(表明访回是否顺利)、响应头 和 内容正文。正文是客户要求的数据,通常是一些 HTML 资源、图片等等。

对 HTTP 还不够了解?可参考 HTTP 协议讲解 这篇文章。

使用 cURL 观察 HTTP 协议

使用 cURL 的参数 -v,–verbose,会显示出 cURL 向服务器发送的命令和其它的一些信息。–verbose 是一个非常有用的命令,尤其是当你想调试或者了解 cURL 和服务器交互过程的时候。

curl –v upyun.com

随后我们就可以观察服务器返回的结果:

mark@Mark-Li:~$ curl -v upyun.com
* Rebuilt URL to: upyun.com/
* Trying 115.231.97.2...
* TCP_NODELAY set
* Connected to upyun.com (115.231.97.2) port (#)
> GET / HTTP/1.1
> Host: upyun.com
> User-Agent: curl/7.58.
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Date: Wed, 13 Mar 2019 05:28:53 GMT
< Content-Type: text/html
< Content-Length: 167
< Connection: keep-alive
< Location: https://www.upyun.com/
<
<html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>openresty/1.13.6.2</center>
</body>
</html>
* Connection #0 to host upyun.com left intact

从输出结果我们可以看到,cURL 命令发起请求所使用的请求方法、请求资源、请求协议版本以及一些请求头。服务器接收到请求后则返回状态码、一些响应头以及网页正文。

如果我们只需要服务器的响应信息的话,可以使用 -i、--include 命令。

curl –i upyun.com

mark@Mark-Li:~$ curl -i upyun.com
HTTP/1.1 Moved Temporarily
Date: Wed, Mar :: GMT
Content-Type: text/html
Content-Length:
Connection: keep-alive
Location: https://www.upyun.com/ <html>
<head><title> Found</title></head>
<body bgcolor="white">
<center><h1> Found</h1></center>
<hr><center>openresty/1.13.6.2</center>
</body>
</html>

如果你觉得上面的信息还不够,那么下面的命令可以查看更详细的通信过程。curl --trace [结果输出保存文件名] http://upyun.com

从上面的例子中,我们可以看到,当我们请求 http://upyun.com 成功之后,服务器会返回一个 302 跳转码,并在响应头中通过 Location 告诉访问者应该跳转到哪里去。

cURL 提供了重定向跟随的功能,通过 -L 参数就可以响应服务器返回的跳转指令了。

curl –L upyun.com

mark@Mark-Li:~$ curl -v upyun.com -Lo /dev/null
* Rebuilt URL to: upyun.com/
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
--:--:-- --:--:-- --:--:-- * Trying 115.231.97.2...
* TCP_NODELAY set
--:--:-- :: --:--:-- * Connected to upyun.com (115.231.97.2) port (#)
> GET / HTTP/1.1
> Host: upyun.com
> User-Agent: curl/7.58.
> Accept: */*
>
< HTTP/1.1 302 Moved Temporarily
< Date: Wed, 13 Mar 2019 06:00:50 GMT
< Content-Type: text/html
< Content-Length: 167
< Connection: keep-alive
< Location: https://www.upyun.com/
<
* Ignoring the response-body
{ [167 bytes data]
100 167 100 167 0 0 104 0 0:00:01 0:00:01 --:--:-- 104
* Connection #0 to host upyun.com left intact
* Issue another request to this URL: 'https://www.upyun.com/'
* Trying 115.231.97.2...
* TCP_NODELAY set
0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0* Connected to www.upyun.com (115.231.97.2) port 443 (#1)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [211 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [104 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2751 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=CN; ST=\U6D59\U6C5F\U7701; L=\U676D\U5DDE\U5E02; O=\U676D\U5DDE\U7EAC\U97F3\U667A\U7F51\U7EDC\U6709\U9650\U516C\U53F8; OU=\U6280\U672F\U90E8; CN=*.upyun.com
* start date: Feb 15 00:00:00 2019 GMT
* expire date: Apr 15 12:00:00 2020 GMT
* subjectAltName: host "www.upyun.com" matched cert's "*.upyun.com"
* issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=GeoTrust RSA CA 2018
* SSL certificate verify ok.
} [5 bytes data]
> GET / HTTP/1.1
> Host: www.upyun.com
> User-Agent: curl/7.58.0
> Accept: */*
>
{ [ bytes data]
< HTTP/1.1 OK
< Content-Type: text/html; charset=utf-
< Content-Length:
< Connection: keep-alive
< Vary: Accept-Encoding
< Server: openresty/1.13.6.2
< Date: Wed, Mar :: GMT
< X-DNS-Prefetch-Control: off
< X-Frame-Options: SAMEORIGIN
< X-Download-Options: noopen
< X-Content-Type-Options: nosniff
< X-XSS-Protection: ; mode=block
< ETag: W/"37148-Mygdw8NXtImEEqWHGE0/u6E0RM8"
< Vary: Accept-Encoding
< X-Kong-Upstream-Latency:
< X-Kong-Proxy-Latency:
<
{ [ bytes data]
220k 220k :: :: --:--:-- 692k
* Connection # to host www.upyun.com left intact

可以看到 cURL 自动跳转访问 https://www.upyun.com/ 去了。

使用 cURL 向服务器发送数据

向服务器提交数据的方法有两种:GET 和 POST 两种方法。

GET 方式比较简单,需要传递的参数直接在 URL 地址中进行传递即可。

例如,向百度提交搜索 curl 的任务,cURL 命令就可以这么发送:

curl -vo /dev/null http://www.baidu.com/s?wd=curl

其中 wd 就是百度服务器接收搜索关键字的参数名。

POST 方法必须把数据和网址分开,我们就需要使用 -X 参数来指定请求方法,-F 参数来传递表单数据。

例如,我想通过又拍云的 FROM API,向自己的存储空间上传一张图片。cURL 命令就可以这么写:

curl -X POST \
http://v0.api.upyun.com/iamge-blog \
-H 'Date: Wed, 13 Mar 2019 06:21:31 GMT' \
-F 'authorization=UPYUN mark:aIa6b0qwnHCffK0NxqPG0U2uBMg=' \
-F policy=eyJidWNrZXQiOiJpYW1nZS1ibG9nIiwic2F2ZS1rZXkiOiIvdGVzdF9jdXJsLmpwZyIsImV4cGlyYXRpb24iOiIxNTYwNDA2ODkyIiwiZGF0ZSI6IldlZCwgMTMgTWFyIDIwMTkgMDY6MjE6MzEgR01UIiwicmV0dXJuLXVybCI6Imh0dHBzOi8vaG9va3MudXB5dW4uY29tL1Nrd0xaN0x2TiJ9 \
-F 'file=@/home/mark/duck.jpg'
Note: Unnecessary use of -X or --request, POST is already inferred.
* Trying 58.222.52.249...
* TCP_NODELAY set
* Connected to v0.api.upyun.com (58.222.52.249) port (#)
> POST /iamge-blog HTTP/1.1
> Host: v0.api.upyun.com
> User-Agent: curl/7.58.
> Accept: */*
> Date: Wed, 13 Mar 2019 06:21:31 GMT
> Content-Length: 35317
> Content-Type: multipart/form-data; boundary=------------------------a38355798f264d25
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 302 Moved Temporarily
< Server: marco/2.8
< Content-Type: text/html
< Connection: keep-alive
< X-Request-Id: d6046ac4c1834027d5ddba6becd020e1
< Date: Wed, 13 Mar 2019 06:34:14 GMT
< x-upyun-height: 339
< Content-Length: 157
< X-Request-Path: 403-zj-fud-209
< Location: https://hooks.upyun.com/SkwLZ7LvN?code=200&image-frames=1&file_size=34675&image-width=604&message=ok&image-type=JPEG&url=%2Ftest_curl.jpg&time=1552458854&image-height=339&mimetype=image%2Fjpeg
< x-upyun-width: 604
< Access-Control-Allow-Origin: *
< x-upyun-frames: 1
* HTTP error before end of send, stop sending

又拍云的 FORM API 上传可参阅[5]。

使用 cURL 测试代理访问

使用 CDN 有时候会发现请求异常,为了确定是 CDN 平台的故障还是源站出现了问题,我们就需要依次来排查。cURL 工具可以使用 -x 参数来指定代理主机端口来访问。

curl -x [protocol://]host[:port] url

例如,我的 CDN 加速域名为 http://test.mark.com,我的源站地址为 1.2.4.8,服务端口为 8080,那么就可以通过 cURL 直接来测试源站响应。

mark@Mark-Li:~$ curl -vo /dev/null test.mark.com -x 1.2.4.8:
* Rebuilt URL to: test.mark.com/
* Trying 1.2.4.8...
* TCP_NODELAY set
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
--:--:-- --:--:-- --:--:-- * Connected to 1.2.4.8 (1.2.4.8) port (#)
> GET http://test.mark.com/ HTTP/1.1
> Host: test.mark.com
> User-Agent: curl/7.58.
> Accept: */*
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 OK
< Server: nginx/1.12.1
< Date: Wed, 13 Mar 2019 08:14:26 GMT
< Content-Type: text/html
< Content-Length: 12569
< Last-Modified: Wed, 13 Mar 2019 07:05:56 GMT
< Connection: keep-alive
< ETag: "5c88abd4-3119"
< Accept-Ranges: bytes
<
{ [12569 bytes data]
100 12569 100 12569 0 0 211k 0 --:--:-- --:--:-- --:--:-- 223k
* Connection #0 to host 1.2.4.8 left intact

这样的话,我们就绕过了 CDN 层,直接去访问源站获取信息了。

使用 cURL 增加或修改请求头

有的时候需要测试网站设置的防盗链有无生效,例如判断 Referer 头、UA 标志或需要携带自定义的请求头,就可以通过 -H 这个参数来实现。

curl -H header:value

例如,http://test.mark.com 开启了 Referer 防盗链,我们现在需要测试防盗链是否生效,就可以这么发送命令:

mark@Mark-Li:~$ curl -vo /dev/null http://test.mark.com/a/meta.jpg -H "Referer:www.baidu.com"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
--:--:-- --:--:-- --:--:-- * Trying 183.131.200.86...
* TCP_NODELAY set
* Connected to test.mark.com (183.131.200.86) port (#)
> GET /a/meta.jpg HTTP/1.1
> Host: test.mark.com
> User-Agent: curl/7.58.
> Accept: */*
> Referer:www.baidu.com
>
< HTTP/1.1 200 OK
< Server: marco/2.8
< Date: Wed, 13 Mar 2019 08:35:26 GMT
< Content-Type: image/jpeg
< Content-Length: 965071
< Connection: keep-alive
< X-Request-Id: e9718d0f066330f2a7c580c332492e1a; db9beca89abeb7dfd848d0cee9540dcb
< X-Source: C/200
< X-Upyun-Content-Length: 965071
< Last-Modified: Thu, 29 Nov 2018 03:13:12 GMT
< X-Upyun-Content-Type: image/jpeg
< ETag: "ec185b942ad06c895935fd75e44076f3"
< Expires: Thu, 21 Mar 2019 07:31:17 GMT
< Cache-Control: max-age=691200
< Accept-Ranges: bytes
< Age: 3849
< Via: T.81.M, V.mix-sd-dst1-082, T.75.H, M.ctn-zj-jgh1-086
<
{ [86016 bytes data]
100 942k 100 942k 0 0 2692k 0 --:--:-- --:--:-- --:--:-- 2692k
* Connection #0 to host test.mark.com left intact

测试跨域请求:

mark@Mark-Li:~$ curl -i http://iamge-blog.test.upcdn.net/a/meta.jpg -H "Origin:www.baidu.com"
HTTP/1.1 OK
Server: marco/2.8
Date: Wed, Mar :: GMT
Content-Type: image/jpeg
Content-Length:
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, PUT, OPTIONS, PATCH, DELETE, POST, HEAD
Access-Control-Max-Age:
Access-Control-Allow-Headers: X-MARK
X-Request-Id: e9718d0f066330f2a7c580c332492e1a; fbbbd43db05fc2fb4ba3e994c5d5eec2
X-Source: U/
X-Upyun-Content-Length:
Last-Modified: Thu, Nov :: GMT
X-Upyun-Content-Type: image/jpeg
ETag: "ec185b942ad06c895935fd75e44076f3"
Expires: Thu, Mar :: GMT
Cache-Control: max-age=
Accept-Ranges: bytes
Age:
Via: T..M, V.mix-sd-dst1-, T..H, M.ctn-zj-jgh1-
access-control-allow-credentials: true

以上就是 cURL 命令工具行的一些常用命令。

接下来我们再来介绍一位网络测试老大哥,dig。

优秀辅助手 DIG

Dig 是 Linux 中的域名解析工具,功能比 Windows 平台上的nslookup 强很多,使用也很方便,Dig 是 Domain Information Groper 的缩写,知道了来源想必大家也就容易记住这条命令了。

Dig 配置

Dig 预装在所有 Linux 发行版和 MacOS 系统中,目前也有大神将 Dig 移植到了 Wndows 平台。大家可以参考这篇安装文档[6]来进行操作。

Dig 调用

一个典型的 dig 调用类似:

dig @server name type

其中:server 待查询名称服务器的名称或 IP 地址,一般指定为 DNS 服务器 name 将要查询的资源记录的名称 type 显示所需的查询类型 - ANY、A、TXT、MX、SIG,以及任何有效查询类型等。如果不提供任何类型参数,dig 将对记录 A 执行查询。

查询 DNS 配置信息

mark@Mark-Li:~$ dig -t NS .

查询域名对应 IP

mark@Mark-Li:~$ dig www.baidu.com

指定 DNS 服务器进行查询

mark@Mark-Li:~$ dig www.baidu.com @9.9.9.9

指定查询 TYPE

例如申请证书的时候,需要在域名解析的地方添加 TXT 记录,这时候就可以通过 dig 来查询。

dig txt test.mark.com
mark@Mark-Li:~$ dig txt test.mark.com

; <<>> DiG 9.11.-1ubuntu1.-Ubuntu <<>> txt test.mark.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id:
;; flags: qr rd ra; QUERY: , ANSWER: , AUTHORITY: , ADDITIONAL: ;; OPT PSEUDOSECTION:
; EDNS: version: , flags:; udp:
;; QUESTION SECTION:
;test.mark.com. IN TXT ;; ANSWER SECTION:
test.mark.com. IN TXT "2019031100000065jk97bbbpuq25wlofojds65ldv7w186idsq00ju" ;; Query time: msec
;; SERVER: 10.0.6.30#(10.0.6.30)
;; WHEN: Wed Mar :: DST
;; MSG SIZE rcvd:

[1] 官方文档中心: https://curl.haxx.se/docs/

[2] cURL 下载中心: https://curl.haxx.se/download.html

[3] Windows 安装: https://blog.51cto.com/9410445/1763891

[4] Linux 安装: https://blog.csdn.net/ivan_ljf/article/details/53966655

[5] 又拍云的 FORM API:https://help.upyun.com/knowledge-base/form_api/

[6] 安装文档: https://blog.51cto.com/5001660/2152132

双剑合璧——掌握 cURL 和 Dig 走天涯的更多相关文章

  1. Spring Cloud & Alibaba 实战 | 第十二篇: 微服务整合Sentinel的流控、熔断降级,赋能拥有降级功能的Feign新技能熔断,实现熔断降级双剑合璧(JMeter模拟测试)

    目录 一. Sentinel概念 1. 什么是Sentinel? 2. Sentinel功能特性 3. Sentinel VS Hystrix 二. Docker部署Sentinel Dashboar ...

  2. MarkDown、Vim双剑合璧

    作为一名软件攻城狮(是的,我从来都以攻城狮自居! 我坚信如今的每一天,都在朝攻城狮迈进.虽然被菜鸟的肉身皮囊裹着,我依然还是怀着攻城狮的内心! 我非常讨厌别人喊我程序猿.虽然这是不争的事实!).... ...

  3. ViewBinding 与 Kotlin 委托双剑合璧

    请点赞关注,你的支持对我意义重大. Hi,我是小彭.本文已收录到 GitHub · Android-NoteBook 中.这里有 Android 进阶成长知识体系,有志同道合的朋友,关注公众号 [彭旭 ...

  4. [转帖]双剑合璧:CPU+GPU异构计算完全解析

    引用自:http://tech.sina.com.cn/mobile/n/2011-06-20/18371792199.shtml 这篇文章写的深入浅出,把异构计算的思想和行业趋势描述的非常清楚,难得 ...

  5. 跟我一起学Go系列:从写测试用例开始仗剑走天涯

    从入门到深入 Go 我们已经走了很长的路,当你想启动多个测试类的时候你是不是想启动多个 main 方法,但是 Go 限制了在同一个 package 下只能有一个 main,所以这条路你是走不通的.那我 ...

  6. ASP.NET Core和Angular 2双剑合璧

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:两个还没有正式发布的东西一起用,是什么效果? 效果当然会很好了(我猜的),那么如何在A ...

  7. JUnit4 与 JMock 之双剑合璧

    引言 单元测试可以保证代码的质量,最大程度降低修复系统 bug 的时间和成本.能被称为测试的阶段有:单元测试.集成测试.系统测试和用户测试.修复系统 bug 的时间和成本随着这些阶段的推移呈指数级增长 ...

  8. Go+Python双剑合璧

    目的 Python调用Go的方法,Python有很多功能强悍又使用简洁的库.而新生军Go的多核心利用率也是非常强悍的.当然这是明面上的优点.反正你有很多理由想要让Python能够调用Go的方法. 实验 ...

  9. AssemblyBuilder以及Activator双剑合璧

    AssemblyBuilder和Activator两个类是DispatchProxy类实现动态代理以及AOP的根本,示例demo可参考 DispatchProxy实现动态代理及AOP .Assembl ...

随机推荐

  1. 操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP)

    原文:操作XML文档遇到的XMLNS问题及解决方法 (C# 和 PHP) 不管是用 PHP 还是 C#, 在操作 XML 的时候我们除了一个节点一个节点去取值之外, 还有一个非常方便的表达式, 就是 ...

  2. 用python & bat写软件安装脚本 + HM NIS Edit自动生成软件安装脚本

    2019-03-11更新:原来NSIS脚本也可以禁用64位文件操作重定向的! 1.在安装脚本的开始处定义 LIBRARY_X64. !include "MUI.nsh"!inclu ...

  3. mysql 服务压缩包安装,用户创建

    wind7上安装mysql记录: 1.下载的包中没有ini配置文件,需要根目录手动创建my.ini文件 内容如下: [client]port=3306default-character-set=utf ...

  4. 处理 Windows Phone 应用中的“后退”按钮 (XAML)

    与电脑不同,所有 Windows Phone 设备都有“后退”按钮,它允许用户在应用的页面之间向后导航.如果用户在转到应用的第一页时再次按“后退”按钮,操作系统会挂起你的应用并将用户导航到应用启动前的 ...

  5. Spring MVC的工作原理,我们来看看其源码实现

    前言 开心一刻 晚上陪老丈人吃饭,突然手机响了,我手贱按了免提……哥们:快出来喝酒!哥几个都在呢!我:今天不行,我现在陪老丈人吃饭呢.哥们:那你抓紧喝,我三杯白酒,把我岳父放倒了才出来的,你也快点.看 ...

  6. JavaScript API for Office Outlook Add-in - “一页纸文档“

    上一篇文章 Office Add-in Model 为 Outlook Mail Add-in 提供的 JavaScript API 介绍 ,简单地在表格中列出了所有的 Object 定义,但是个人感 ...

  7. CKEditor 4.5 beta 发布,可视化 HTML 编辑器

    分享 <关于我> 分享  [中文纪录片]互联网时代                 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...

  8. c#透明panel

    先看下效果 纯透明的pane,然后设置一个半透明的图片,可以看出来显示了父控件的button 看代码 public partial class PanelEx : Panel { protected ...

  9. Delphi Berlin 10.1.2 FMX用TMessageManager处理自定义消息

    看FMX代码,发现有两种消息处理的实现方式,一种是用TMessageManager来实现自定义的消息,另外一种象TEdit中的实现,直接声明消息方法.   早前,看过文章说TMessageManage ...

  10. <iOS小技巧> 返回上级目录操作Goback()方法

    Goback()方法功能:返回上一级界面,通过判断 popViewControllerAnimated 类型是否为空,来判断是present还是pop出来,然后直接做了releaseSelf操作: - ...