增加图注释

This commit is contained in:
xiemengjun
2013-01-16 23:11:49 +08:00
parent 133d9976b3
commit e54f54988d
27 changed files with 152 additions and 10 deletions

10
01.1.md
View File

@@ -40,6 +40,8 @@ Go使用[Mercurial][hg]进行版本管理首先你必须安装了Mercurial
![](images/1.1.mac.png?raw=true)
图1.1 源码安装之后执行Go命令的图
如果出现Go的Usage信息那么说明Go已经安装成功了如果出现该命令不存在那么可以检查一下自己的PATH环境变中是否包含了Go的安装目录。
@@ -74,9 +76,7 @@ Linux系统用户可通过在Terminal中执行命令`uname -a`来查看系统信
访问[下载地址][downlink]32位系统下载go1.0.3.darwin-386.pkg64位系统下载go1.0.3.darwin-amd64.pkg双击下载文件一路默认安装点击下一步这个时候go已经安装到你的系统中默认已经在PATH中增加了相应的`~/go/bin`,这个时候打开终端,输入`go`
看到如下图片说明已经安装成功
![](images/1.1.mac.png?raw=true)
看到类似上面源码安装成功的图片说明已经安装成功
如果出现go的Usage信息那么说明go已经安装成功了如果出现该命令不存在那么可以检查一下自己的PATH环境变中是否包含了go的安装目录。
@@ -92,7 +92,9 @@ Linux系统用户可通过在Terminal中执行命令`uname -a`来查看系统信
然后执行`go`
看到类似上面mac安装成功的图片说明已经安装成功
![](images/1.1.linux.png?raw=true)
图1.2 Linux系统下安装成功之后执行go显示的信息
如果出现go的Usage信息那么说明go已经安装成功了如果出现该命令不存在那么可以检查一下自己的PATH环境变中是否包含了go的安装目录。

View File

@@ -6,6 +6,8 @@
![](images/1.3.go.png?raw=true)
图1.3 Go命令显示详细的信息
这些命令对于我们平时编写的代码非常有用,接下来就让我们了解一些常用的命令。
## go build

39
01.4.md
View File

@@ -8,6 +8,8 @@
![](images/1.4.liteide.png?raw=true)
图1.4 LiteIDE主界面
**LiteIDE主要特点**
* 支持主流操作系统
@@ -100,15 +102,23 @@
这里将介绍Sublime Text 2以下简称Sublime+GoSublime+gocode+MarGo的组合那么为什么选择这个组合呢
- 自动化提示代码,如下图所示
![](images/1.4.sublime1.png?raw=true)
![](images/1.4.sublime1.png?raw=true)
图1.5 sublime自动化提示界面
- 保存的时候自动格式化代码让您编写的代码更加美观符合Go的标准。
- 支持项目管理
![](images/1.4.sublime2.png?raw=true)
![](images/1.4.sublime2.png?raw=true)
图1.6 sublime项目管理界面
- 支持语法高亮
- Sublime Text 2可免费使用只是保存次数达到一定数量之后就会提示是否购买点击取消继续用和正式注册版本没有任何区别。
接下来就开始讲如何安装,下载[Sublime](http://www.sublimetext.com/)
接下来就开始讲如何安装,下载[Sublime](http://www.sublimetext.com/)
根据自己相应的系统下载相应的版本然后打开Sublime对于不熟悉Sublime的同学可以先看一下这篇文章[Sublime Text 2 入门及技巧](http://lucifr.com/139225/sublime-text-2-tricks-and-tips/)
@@ -120,6 +130,8 @@
![](images/1.4.sublime3.png?raw=true)
图1.7 sublime包管理
2. 接下来安装gocode和MarGo。
打开终端运行如下代码需要git
@@ -134,6 +146,8 @@
![](images/1.4.sublime4.png?raw=true)
图1.8 sublime安装插件界面
这个时候输入GoSublime按确定就开始安装了。同理应用于SidebarEnhancements和Go Build。
4. 验证是否安装成功你可以打开Sublime打开main.go看看语法是不是高亮了输入`import`是不是自动化提示了,`import "fmt"`之后,输入`fmt.`是不是自动化提示有函数了。
@@ -146,7 +160,9 @@
## Vim
Vim是从vi发展出来的一个文本编辑器, 代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。
![](images/1.4.vim.png?raw=true)
![](images/1.4.vim.png?raw=true)
图1.9 VIM编辑器自动化提示Go界面
1. 配置vim高亮显示
@@ -190,6 +206,8 @@ Emacs传说中的神器她不仅仅是一个编辑器它是一个整合环
![](images/1.4.emacs.png?raw=true)
图1.10 Emacs编辑Go主界面
1. 配置Emacs高亮显示
cp $GOROOT/misc/emacs/* ~/.emacs.d/
@@ -325,6 +343,8 @@ Eclipse也是非常常用的开发利器以下介绍如何使用Eclipse来编
![](images/1.4.eclipse1.png?raw=true)
图1.11 Eclipse编辑Go的主界面
1. 首先下载并安装好[Eclipse](http://www.eclipse.org/)
2. 下载[goeclipse](https://code.google.com/p/goclipse/)插件
@@ -355,13 +375,20 @@ Eclipse也是非常常用的开发利器以下介绍如何使用Eclipse来编
![](images/1.4.eclipse2.png?raw=true)
图1.12 设置Go的一些基础信息
(2).配置Gocode可选代码补全设置Gocode路径为之前生成的gocode.exe文件
![](images/1.4.eclipse3.png?raw=true)
图1.13 设置gocode信息
(3).配置GDB可选做调试用设置GDB路径为MingW安装目录下的gdb.exe文件
![](images/1.4.eclipse4.png?raw=true)
图1.14 设置GDB信息
6. 测试是否成功
@@ -369,9 +396,13 @@ Eclipse也是非常常用的开发利器以下介绍如何使用Eclipse来编
![](images/1.4.eclipse5.png?raw=true)
图1.15 新建项目编辑文件
调试如下要在console中用输入命令来调试
![](images/1.4.eclipse6.png?raw=true)
图1.16 调试Go程序
## links

10
02.2.md
View File

@@ -182,6 +182,8 @@ Go内置有一个`error`类型专门用来处理错误信息Go的`package`
![](images/2.2.basic.png?raw=true)
图2.1 Go数据格式的存储
## 一些技巧
### 分组声明
@@ -277,6 +279,8 @@ Go之所以会那么简洁是因为它有一些默认的行为
![](images/2.2.array.png?raw=true)
图2.2 多维数组的映射关系
### slice
@@ -313,6 +317,8 @@ Go之所以会那么简洁是因为它有一些默认的行为
![](images/2.2.slice.png?raw=true)
图2.3 slice和array的对应关系图
slice有一些简便的操作
- `slice`的默认开始位置是0`ar[:n]`等价于`ar[0:n]`
@@ -352,6 +358,8 @@ slice有一些简便的操作
![](images/2.2.slice2.png?raw=true)
图2.4 slice对应数组的信息
对于`slice`有几个有用的内置函数:
- `len` 获取`slice`的长度
@@ -428,6 +436,8 @@ slice有一些简便的操作
![](images/2.2.makenew.png?raw=true)
图2.5 make和new对应底层的内存分配
关于“零值”所指并非是空值而是一种“变量未填充前”的默认值通常为0。
此处罗列 部分类型 的 “零值”

View File

@@ -455,6 +455,8 @@ Go程序会自动调用`init()`和`main()`,所以你不需要在任何地方
![](images/2.3.init.png?raw=true)
图2.6 main函数引入包初始化流程图
### import
我们在写Go代码的时候经常用到import这个命令用来导入包文件而我们经常看到的方式参考如下

View File

@@ -126,6 +126,8 @@ Go语言中也和C或者其他语言一样我们可以声明新的类型
![](images/2.4.student_struct.png?raw=true)
图2.7 Student和Human的方法继承
我们看到Student访问属性age和name的时候就像访问自己所有用的字段一样匿名字段就是这样能够实现字段的继承。是不是很酷啊还有比这个更酷的呢那就是student还能访问Human这个字段作为字段名。请看下面的代码是不是更酷了。
mark.Human = Human{"Marcus", 55, 220}

View File

@@ -30,6 +30,8 @@
![](images/2.5.rect_func_without_receiver.png?raw=true)
图2.8 方法和struct的关系图
很显然,这样的实现并不优雅,并且从概念上来说"面积"是"形状"的一个属性,它是属于这个特定的形状的,就像长方形的长和宽一样。
基于上面的原因所以就有了`method`的概念,`method`是附属在一个给定的类型上的,他的语法和函数的声明语法几乎一样,只是在`func`后面增加了一个receiver(也就是method所依从的主体)。
@@ -95,6 +97,8 @@ method的语法如下
![](images/2.5.shapes_func_with_receiver_cp.png?raw=true)
图2.9 不同struct的method不同
在上例method area() 分别属于Rectangle和Circle 于是他们的 Receiver 就变成了Rectangle 和 Circle, 或者说这个area()方法 是由 Rectangle/Circle 发出的。
>值得说明的一点是图示中method用虚线标出意思是此处方法的Receiver是以值传递而非引用传递是的Receiver还可以是指针, 两者的差别在于, 指针作为Receiver会对实例对象的内容发生操作,而普通类型作为Receiver仅仅是以副本作为操作对象,并不对原实例对象发生操作。后文对此会有详细论述。

13
03.1.md
View File

@@ -6,6 +6,8 @@
![](images/3.1.web2.png?raw=true)
图3.1 用户访问一个Web站点的过程
一个Web服务器也被称为HTTP服务器它通过HTTP协议与客户端通信。这个客户端通常指的是Web浏览器(其实手机端客户端内部也是浏览器实现的)。
Web服务器的工作原理可以简单地归纳为
@@ -34,6 +36,8 @@ URL(Uniform Resource Locator)是“统一资源定位符”的英文缩写,用
![](images/3.1.dns_hierachy.png?raw=true)
图3.2 DNS工作原理
更详细的DNS解析的过程如下这个过程有助于我们理解DNS的工作模式
1. 在浏览器中输入www.qq.com域名操作系统会先检查自己本地的hosts文件是否有这个网址映射关系如果有就先调用这个IP地址映射完成域名解析。
@@ -50,6 +54,8 @@ URL(Uniform Resource Locator)是“统一资源定位符”的英文缩写,用
![](images/3.1.dns_inquery.png?raw=true)
图3.3 DNS解析的整个流程
> 所谓 `递归查询过程` 就是 “查询的递交者” 更替, 而 `迭代查询过程` 则是 “查询的递交者”不变。
>
> 举个例子来说,你想知道某个一起上法律课的女孩的电话,并且你偷偷拍了她的照片,回到寝室告诉一个很仗义的哥们儿,这个哥们儿二话没说,拍着胸脯告诉你,甭急,我替你查(此处完成了一次递归查询,即,问询者的角色更替)。然后他拿着照片问了学院大四学长学长告诉他这姑娘是xx系的然后这哥们儿马不停蹄又问了xx系的办公室主任助理同学助理同学说是xx系yy班的然后很仗义的哥们儿去xx系yy班的班长那里取到了该女孩儿电话。(此处完成若干次迭代查询,即,问询者角色不变,但反复更替问询对象)最后,他把号码交到了你手里。完成整个查询过程。
@@ -83,8 +89,12 @@ HTTP协议是无状态的同一个客户端的这次请求和上次请求是
![](images/3.1.http.png?raw=true)
图3.4 fiddler抓取的GET信息
![](images/3.1.httpPOST.png?raw=true)
图3.5 fiddler抓取的POST信息
**我们可以看到GET请求消息体为空POST请求带有消息体**
HTTP协议定义了很多与服务器交互的请求方法最基本的有4种分别是GET,POST,PUT,DELETE. 一个URL地址用于描述一个网络上的资源而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查删4个操作。 我们最常见的就是GET和POST了。GET一般用于获取/查询资源信息而POST一般用于更新资源信息.
@@ -120,6 +130,7 @@ Response包中的第一行叫做状态行由HTTP协议版本号 状态码
![](images/3.1.response.png?raw=true)
图3.6 访问一次网站的全部请求信息
### HTTP协议是无状态的和Connection: keep-alive的区别
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。
@@ -134,6 +145,8 @@ Keep-Alive不会永久保持连接它有一个保持时间可以在不同
![](images/3.1.web.png?raw=true)
图3.7 一次请求的request和response
上面这张图我们可以了解到整个的通讯过程同时细心的读者是否注意到了一点一个URL请求但是左边栏里面为什么会有那么多的资源请求(这些都是静态文件go对于静态文件有专门的处理方式)。
这个就是浏览器的一个功能第一次请求url服务器端返回的是html页面然后浏览器开始渲染HTML当解析到HTML DOM里面的图片连接css脚本和js脚本的链接浏览器就会自动发起一个请求静态资源的HTTP请求获取相对应的静态资源然后浏览器就会渲染出来最终将所有资源整合、渲染完整展现在我们面前的屏幕上。

View File

@@ -48,6 +48,8 @@
![](images/3.2.goweb.png?raw=true)
图3.8 用户访问Web之后服务器端打印的信息
我们看到上面的代码要编写一个web服务器很简单只要调用http包的两个函数就可以了。
>如果你以前是PHP程序员那你也许就会问我们的nginx、apache服务器不需要吗Go就是不需要这些因为他直接就监听tcp端口了做了nginx做的事情然后sayhelloName这个其实就是我们写的逻辑函数了也就是php里面的控制层controller函数类似。

View File

@@ -19,6 +19,8 @@ Handler处理请求和生成返回信息的处理逻辑
![](images/3.3.http.png?raw=true)
图3.9 http包执行流程
1. 创建Listen Socket, 监听指定的端口, 等待客户端请求到来。
2. Listen Socket接受客户端的请求, 得到Client Socket, 接下来通过Client Socket与客户端通信。
@@ -41,6 +43,8 @@ Handler处理请求和生成返回信息的处理逻辑
![](images/3.3.illustrator.png?raw=true)
图3.10 一个http连接处理流程
至此我们的三个问题已经全部得到了解答你现在对于Go如何让Web跑起来的是否已经基本了解呢

View File

@@ -74,6 +74,8 @@ login函数中我们根据`r.Method`来判断是显示登录界面还是处理
![](images/4.1.login.png?raw=true)
图4.1 用户登录界面
我们输入用户名和密码之后发现在服务器端是不会打印出来任何输出的为什么呢默认情况下Handler里面是不会自动解析form的必须显式的调用`r.ParseForm()`后,你才能对这个表单数据进行操作。我们修改一下代码,在`fmt.Println("username:", r.Form["username"])`之前加一行`r.ParseForm()`,重新编译,再次测试输入递交,现在是不是在服务器端有输出你的输入的用户名和密码了。
`r.Form`里面包含了所有请求的参数比如URL中query-string、POST的数据、PUT的数据所有当你在URL的query-string字段和POST冲突时会保存成一个slice里面存储了多个值Go官方文档中说在接下来的版本里面将会把POST、GET这些数据分离开来。
@@ -82,6 +84,8 @@ login函数中我们根据`r.Method`来判断是显示登录界面还是处理
![](images/4.1.slice.png?raw=true)
图4.2 服务器端打印接受到的信息
`request.Form`是一个url.Values类型里面存储的是对应的类似`key=value`的信息下面展示了可以对form数据进行的一些操作:
v := url.Values{}

View File

@@ -23,6 +23,8 @@
![](images/4.3.escape.png?raw=true)
图4.3 Javascript过滤之后的输出
Go的html/template包默认帮你过滤了html标签但是有时候你只想要输出这个`<script>alert()</script>`看起来正常的信息该怎么处理请使用text/template。请看下面的例子
import "text/template"

View File

@@ -46,6 +46,8 @@
![](images/4.4.token.png?raw=true)
图4.4 增加token之后在客户端输出的源码信息
我们看到token已经有输出值你可以不断的刷新可以看到这个值在不断的变化。这样就保证了每次显示form表单的时候都是唯一的用户递交的表单保持了唯一性。
我们的解决方案可以防止非恶意的攻击,并能使恶意用户暂时不知所措,然后,它却不能排除所有的欺骗性的动机,对此类情况还需要更复杂的工作。

View File

@@ -78,6 +78,7 @@
![](images/4.5.upload2.png?raw=true)
图4.5 打印文件上传后服务器端接受的信息
## 客户端上传文件

View File

@@ -60,6 +60,8 @@ MongoDB是一个高性能开源无模式的文档型数据库是一个
![](images/5.6.mongodb.png?raw=true)
图5.1 MongoDB和Mysql的操作对比图
目前Go支持mongoDB最好的驱动就是[mgo](http://labix.org/mgo)这个驱动目前最有可能成为官方的pkg。
下面我将演示如果通过Go来操作mongoDB

View File

@@ -11,15 +11,21 @@ cookie简而言之就是在本地计算机保存一些用户操作的历史
![](images/6.1.cookie2.png?raw=true)
图6.1 cookie的原理图
session简而言之就是在服务器上保存用户操作的历史信息。服务器使用session id来标识sessionsession id由服务器负责产生保证随机性与唯一性相当于一个随机密钥避免在握手或传输中暴露用户真实密码。但该方式下仍然需要将发送请求的客户端与session进行对应所以可以借助cookie机制来获取客户端的标识即session id也可以通过GET方式将id提交给服务器。
![](images/6.1.session.png?raw=true)
图6.2 session的原理图
## cookie
Cookie是由浏览器维持的存储在客户端的一小段文本信息伴随着用户请求和页面在Web服务器和浏览器之间传递。用户每次访问站点时Web应用程序都可以读取cookie包含的信息。浏览器设置里面有cookie隐私数据选项打开它可以看到很多已访问网站的cookies如下图所示
![](images/6.1.cookie.png?raw=true)
图6.3 浏览器端保存的cookie信息
cookie是有时间限制的根据生命期不同分成两种会话cookie和持久cookie
如果不设置过期时间则表示这个cookie生命周期为从创建到浏览器关闭止只要关闭浏览器窗口cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。

View File

@@ -27,19 +27,27 @@ count.gtpl的代码如下所示
![](images/6.4.hijack.png?raw=true)
图6.4 浏览器端显示count数
随着刷新数字将不断增长当数字显示为6的时候打开浏览器(以chrome为例的cookie管理器可以看到类似如下的信息
![](images/6.4.cookie.png?raw=true)
图6.5 获取浏览器端保存的cookie
下面这个步骤最为关键: 打开另一个浏览器(这里我打开了firefox浏览器),复制chrome地址栏里的地址到新打开的浏览器的地址栏中。然后打开firefox的cookie模拟插件新建一个cookie把按上图中cookie内容原样在firefox中重建一份:
![](images/6.4.setcookie.png?raw=true)
图6.6 模拟cookie
回车后,你将看到如下内容:
![](images/6.4.hijacksuccess.png?raw=true)
图6.7 劫持session成功
可以看到虽然换了浏览器但是我们却获得了sessionID然后模拟了cookie存储的过程。这个例子是在同一台计算机上做的不过即使换用两台来做其结果仍然一样。此时如果交替点击两个浏览器里的链接你会发现它们其实操纵的是同一个计数器。不必惊讶此处firefox盗用了chrome和goserver之间的维持会话的钥匙即gosessionid这是一种类型的“会话劫持”。在goserver看来它从http请求中得到了一个gosessionid由于HTTP协议的无状态性它无法得知这个gosessionid是从chrome那里“劫持”来的它依然会去查找对应的session并执行相关计算。与此同时 chrome也无法得知自己保持的会话已经被“劫持”。
## session劫持防范
### cookieonly和token

View File

@@ -6,6 +6,8 @@
![](images/7.4.template.png?raw=true)
图7.1 模板机制图
Web应用反馈给客户端的信息中的大部分内容是静态的不变的而另外少部分是根据用户的请求来动态生成的例如要显示用户的访问记录列表。用户之间只有记录数据是不同的而列表的样式则是固定的此时采用模板可以复用很多静态代码。
## Go模板使用

View File

@@ -10,6 +10,8 @@ Socket起源于Unix而Unix基本哲学之一就是“一切皆文件”
![](images/8.1.socket.png?raw=true)
图8.1 七层网络协议图
使用TCP/IP协议的应用程序通常采用应用编程接口UNIX BSD的套接字socket和UNIX System V的TLI已经被淘汰来实现网络进程之间的通信。就目前而言几乎所有的应用程序都是采用socket而现在又是网络时代网络中进程通信是无处不在这就是为什么说“一切皆Socket”。
## Socket基础知识

View File

@@ -13,6 +13,8 @@ WebSocket URL的起始输入是ws://或是wss://在SSL上。下图展示
![](images/8.2.websocket.png?raw=true)
图8.2 WebSocket原理图
## WebSocket原理
WebSocket的协议颇为简单在第一次handshake通过以后连接便建立成功其后的通讯数据都是以”\x00″开头以”\xFF”结尾。在客户端这个是透明的WebSocket组件会自动将原始数据“掐头去尾”。
@@ -20,6 +22,8 @@ WebSocket的协议颇为简单在第一次handshake通过以后连接便
![](images/8.2.websocket2.png?raw=true)
图8.3 WebSocket的request和response信息
在请求中的"Sec-WebSocket-Key"是随机的对于整天跟编码打交到的程序员一眼就可以看出来这个是一个经过base64编码后的数据。服务器端接收到这个请求之后需要把这个字符串连接上一个固定的字符串
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
@@ -136,6 +140,8 @@ WebSocket分为客户端和服务端接下来我们将实现一个简单的
![](images/8.2.websocket3.png?raw=true)
图8.4 WebSocket服务器端接收到的信息
通过上面的例子我们看到客户端和服务器端实现WebSocket非常的方便Go的源码net分支中已经实现了这个的协议我们可以直接拿来用目前随着HTML5的发展我想未来WebSocket会是Web开发的一个重点我们需要储备这方面的知识。

View File

@@ -37,17 +37,23 @@ Web应用要满足REST最重要的原则是:客户端和服务器之间的交互
![](images/8.3.rest2.png?raw=true)
图8.5 REST架构图
当REST架构的约束条件作为一个整体应用时将生成一个可以扩展到大量客户端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构改进了子系统之间交互的可见性。REST简化了客户端和服务器的实现而且对于使用REST开发的应用程序更加容易扩展。
下图展示了REST的扩展性
![](images/8.3.rest.png?raw=true)
图8.6 REST的扩展性
## RESTful的实现
Go没有为REST提供直接支持但是因为RESTful是基于HTTP协议实现的所以我们可以利用`net/http`包来自己实现当然需要针对REST做一些改造REST是根据不同的method来处理相应的资源目前已经存在的很多自称是REST的应用其实并没有真正的实现REST我暂且把这些应用根据实现的method分成几个级别请看下图
![](images/8.3.rest3.png?raw=true)
图8.7 REST的level分级
上图展示了我们目前实现REST的三个level我们在应用开发的时候也不一定全部按照RESTful的规则全部实现他的方式因为有些时候完全按照RESTful的方式未必是可行的RESTful服务充分利用每一个HTTP方法包括`DELETE``PUT`。可有时HTTP客户端只能发出`GET``POST`请求:
- HTML标准只能通过链接和表单支持`GET``POST`。在没有Ajax支持的网页浏览器中不能发出`PUT``DELETE`命令

View File

@@ -9,6 +9,8 @@ RPCRemote Procedure Call Protocol——远程过程调用协议是一
![](images/8.4.rpc.png?raw=true)
图8.8 RPC工作流程图
运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:
- 1.调用客户端句柄;执行传送参数

View File

@@ -12,6 +12,8 @@ CSRFCross-site request forgery中文名称跨站请求伪造
![](images/9.1.csrf.png?raw=true)
图9.1 CSRF的攻击过程
从上图可以看出要完成一次CSRF攻击受害者必须依次完成两个步骤
- 1.登录受信任网站A并在本地生成Cookie 。

View File

@@ -5,8 +5,12 @@
![](images/13.1.gopath.png?raw=true)
图13.1 环境变量GOPATH设置
![](images/13.1.gopath2.png?raw=true)
图13.2 工作目录在$gopath/src下
## 应用程序流程图
博客系统是基于模型-视图-控制器这一设计模式的。MVC是一种将应用程序的逻辑层和表现层进行分离的结构方式。在实践中由于表现层从Go中分离了出来所以它允许你的网页中只包含很少的脚本。
@@ -14,10 +18,12 @@
- 视图 (View) 是展示给用户的信息的结构及样式。一个视图通常是一个网页但是在Go中一个视图也可以是一个页面片段如页头、页尾。它还可以是一个 RSS 页面或其它类型的“页面”Go实现的template包已经很好的实现了View层中的部分功能。
- 控制器 (Controller) 是模型、视图以及其他任何处理HTTP请求所必须的资源之间的中介并生成网页。
下图显示了项目设计中博客系统的数据流是如何贯穿整个系统:
下图显示了项目设计中框架的数据流是如何贯穿整个系统:
![](images/13.1.flow.png?raw=true)
图13.3 框架的数据流
1. main.go作为应用入口初始化一些运行博客所需要的基本资源配置信息监听端口。
2. 路由功能检查HTTP请求根据URL以及method来确定谁(控制层)来处理请求的转发资源。
3. 如果缓存文件存在,它将绕过通常的流程执行,被直接发送给浏览器。

View File

@@ -36,11 +36,15 @@ Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。Boot
![](images/14.1.bootstrap.png?raw=true)
图14.1 bootstrap站点
接下来我们利用bootstrap集成到beego框架里面来快速的建立一个漂亮的站点。
1. 首先把下载的bootstrap目录放到我们的项目目录取名为static如下截图所示
![](images/14.1.bootstrap2.png?raw=true)
图14.2 项目中静态文件目录结构
2. 因为beego默认设置了StaticDir的值所以如果你的静态文件目录是static的话就无须再增加了
@@ -61,6 +65,8 @@ Bootstrap是Twitter推出的一个开源的用于前端开发的工具包。Boot
![](images/14.1.bootstrap3.png?raw=true)
图14.3 构建的基于bootstrap的站点界面
这些模板和格式bootstrap官方都有提供这边就不在重复贴代码大家可以上bootstrap官方网站学习如何编写这样的模板。

View File

@@ -131,13 +131,20 @@ oauth和oauth2是目前比较流行的两种认证方式还好第三方有一
![](images/14.4.github.png?raw=true)
图14.4 显示带有登录按钮的首页
然后点击链接出现如下界面:
![](images/14.4.github2.png?raw=true)
图14.5 点击登录按钮后显示github的授权页
然后点击Authorize app就出现如下界面
![](images/14.4.github3.png?raw=true)
![](images/14.4.github3.png?raw=true)
图14.6 授权登录之后显示的获取到的github信息页
## 自定义认证
自定义的认证一般都是和session结合的验证的如下代码来源于一个基于beego的开源博客

View File

@@ -55,10 +55,14 @@ Go语言有一个非常棒的设计就是标准库里面带有代码的性能监
然后你就可以在浏览器中打开如下URL就看到如下界面
![](images/14.6.pprof.png?raw=true)
图14.7 系统当前goroutine、heap、thread信息
点击goroutine我们可以看到很多详细的信息
![](images/14.6.pprof2.png?raw=true)
图14.8 显示当前goroutine的详细信息
我们还可以通过命令行获取更多详细的信息
go tool pprof http://localhost:8080/debug/pprof/profile
@@ -93,6 +97,8 @@ Go语言有一个非常棒的设计就是标准库里面带有代码的性能监
![](images/14.6.pprof3.png?raw=true)
图14.9 展示的执行流程信息
## links
* [目录](<preface.md>)
* 上一节: [多语言支持](<14.5.md>)