响应式旅游网站源码分享程序(响应式网站源代码)

大家好,如果您还对响应式旅游网站源码分享程序不太了解,没有关系,今天就由本站为大家分享响应式旅游网站源码分享程序的知识,包括响应式网站源代码的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

1、HTTP响应报文结构

前面几篇教程我们了解了如何在Go语言中解析用户请求信息,包括表单字段和文件上传,接下来,我们来看看处理完请求后,如何将响应发送给客户端。HTTP响应的报文结构如下所示:

HTTP响应报文结构

和HTTP请求报文结构类似,响应报文也可以分为三部分:状态行、响应头(首部字段)和响应主体。

首先是状态行,在状态行中包含了HTTP协议版本和响应状态码,200OK表示响应成功,更多状态码信息(常见的有404、403、500、301等)可以网上查看下HTTP协议或者阅读HTTP响应状态码这篇文章了解。

然后是响应头,其中包含了HTTP响应的首部字段,比如内容类型/编码、缓存控制、Cookie信息等。

最后是响应实体,对于API接口来说,通常就是返回的XML/JSON格式数据,对于HTML视图响应,就是一个标准的HTML文档,如上图所示。响应头和响应报文之间通过两个换行符分隔。

2、ResponseWriter接口

在Go语言中,客户端请求信息都封装到了Request对象,但是发送给客户端的响应并不是Response对象,而是ResponseWriter:

funcHome(whttp.ResponseWriter,r*http.Request){\nio.WriteString(w,&34;)\n}\n

ResponseWriter是处理器用来创建HTTP响应的接口,其源码结构如下所示:

typeResponseWriterinterface{\n//用于设置/获取所有响应头信息\nHeader()Header\n//用于写入数据到响应实体\nWrite([]byte)(int,error)\n//用于设置响应状态码\nWriteHeader(statusCodeint)\n}\n

实际上,在底层支撑ResponseWriter的结构体就是http.response,详见net/http包下server.go中的readRequest方法(调用处理器处理HTTP请求时调用了该方法返回响应对象),并且其返回值是response指针,这也是为什么在处理器方法声明的时候Request是指针类型,而ResponseWriter不是,实际上在底层,响应对象也是指针类型(因为在应用代码中需要设置响应头和响应实体,所以响应对象理应是指针类型):

func(c*conn)readRequest(ctxcontext.Context)(w*response,errerror){\n…\nw=&response{\nconn:c,\ncancelCtx:cancelCtx,\nreq:req,\nreqBody:req.Body,\nhandlerHeader:make(Header),\ncontentLength:-1,\ncloseNotifyCh:make(chanbool,1),\nwants10KeepAlive:req.wantsHttp10KeepAlive(),\nwantsClose:req.wantsClose(),\n}\nifisH2Upgrade{\nw.closeAfterReply=true\n}\nw.cw.res=w\nw.w=newBufioWriterSize(&w.cw,bufferBeforeChunkingSize)\nreturnw,nil\n}\n

response结构体定义和ResponseWriter一样都位于server.go,感兴趣的同学可以去看下源码,不过由于response对外不可见,所以只能通过ResponseWriter接口访问它。两者之间的关系是ResponseWriter是一个接口,而http.response实现了它。当我们引用ResponseWriter时,实际上引用的是http.response对象实例。

3、设置响应状态码

如上面的ResponseWriter接口定义源码所示,它包含三个方法:

WriteHeaderHeaderWrite

WriteHeader这个方法名有点误导,其实它并不是用来设置响应头的,该方法支持传入一个整型数据用来表示响应状态码,如果不调用该方法的话,默认响应状态码是200OK。

WriteHeader的主要作用是在API接口中返回错误码,我们在goblog/handlers/common.go中新增一个处理器方法Error,并通过w.WriteHeader返回一个401未认证状态码(注意在运行时w代表的是对应的response对象实例,而不是接口):

funcError(whttp.ResponseWriter,r*http.Request){\nw.WriteHeader(401)\nfmt.Fprintln(w,&34;)\n}\n

注:这里通过fmt.Fprintln将文本字符串写入响应对象。

然后在routes/web.go中添加一个路由与之映射:

WebRoute{\n&34;,\n&34;,\n&34;,\nhandlers.Error,\n},\n

重启HTTP服务器,通过curl访问http://localhost:8080/error,返回的完整响应报文如下:

可以看到响应状态码是401Unauthorized,表示该接口需要认证后才能访问。这里,我们在运行curl时带上-i选项,以便可以看到完整的响应报文,第一行是响应状态行,然后是响应头信息,响应头每一行是一个键值对映射,通过冒号分隔,左侧是字段名,右侧是字段值,最后是响应实体,也就是我们在代码中写入的响应数据,响应实体和响应头之间通过一个空行分隔(两个换行符)。

5、设置响应头

Header方法用于设置响应头信息,我们可以通过w.Header().Set方法设置响应头(w.Header()方法返回的是Header响应头对象,它和请求头共用一个结构体,因此请求头上支持的方法这里都支持,比如可以通过w.Header().Add方法新增响应头),这里我们设置一个301重定向响应,只需要通过w.WriteHeader方法将响应状态码设置为301,再通过w.Header().Set方法将负责重定向的响应头Location设置为一个可访问域名即可。

在goblog/handlers/common.go中新建一个处理器方法Redirect,在其中编写重定向实现代码如下:

funcRedirect(whttp.ResponseWriter,r*http.Request){\n//设置一个301重定向\nw.Header().Set(&34;,&34;)\nw.WriteHeader(301)\n}\n

对于重定向请求,无需设置响应实体,另外需要注意的是w.Header().Set必须在w.WriteHeader之前调用,因为一旦调用w.WriteHeader之后,就不能对响应头进行设置了。

接下来,在routes/web.go中注册对应的重定向路由:

WebRoute{\n&34;,\n&34;,\n&34;,\nhandlers.Redirect,\n},\n

重启HTTP服务器,通过curl访问该路由可以清楚看到响应被重定向,并且响应实体为空:

如果是在浏览器中访问的话,页面就会跳转到https://xueyuanjun.com:

6、写入数据到响应实体

Write方法用于写入数据到HTTP响应实体,如果调用Write方法时还不知道Content-Type,会通过数据的前512个字节进行判断。

返回文本字符串

以goblog/handlers/common.go中定义的Home处理器方法为例,我们可以通过w.Write写入一段欢迎文本到响应实体:

funcHome(whttp.ResponseWriter,r*http.Request){\nw.Write([]byte(&34;));\n}\n

由于Write方法接受的参数类型是[]byte切片,所以需要将字符串转换为字节切片类型。启动HTTP服务器,通过curl访问首页,就可以看到返回的文本信息了:

返回HTML文档

如果要返回HTML文档,可以这么写入响应数据:

funcHome(whttp.ResponseWriter,r*http.Request){\n//w.Write([]byte(&34;));\nhtml:=`<html>\n<head>\n<title>学院君个人网站</title>\n</head>\n<body>\n<h1>欢迎访问学院君个人网站</h1>\n</body>\n</html>`\nw.Write([]byte(html))\n}\n

当然,后面介绍视图模板后,可以通过视图模板渲染HTML文档,这里我们先通过一个简单的包含HTML文档信息的字符串替代,重启HTTP服务器,通过浏览器访问,就可以看到对应的HTML视图了:

此外,由于响应数据的内容类型变成了HTML,在响应头中,也可以看到Content-Type也自动调整成了text/html,不再是纯文本格式。这里的Content-Type就是根据传入的数据自行判断出来的。

返回JSON格式数据

当然,我们也可以返回JSON格式数据:

typeGreetingstruct{\nMessagestring`json:&34;`\n}\nfuncHome(whttp.ResponseWriter,r*http.Request){\n//返回文本字符串\n//w.Write([]byte(&34;));\n//返回HTML文档\n/*html:=`<html>\n<head>\n<title>学院君个人网站</title>\n</head>\n<body>\n<h1>欢迎访问学院君个人网站</h1>\n</body>\n</html>`\nw.Write([]byte(html))*/\n//返回JSON格式数据\ngreeting:=Greeting{\n&34;,\n}\nmessage,_:=json.Marshal(greeting)\nw.Write(message)\n}\n

重启HTTP服务器,在浏览器中访问http://localhost:8080:

虽然返回的确实是合法的JSON格式数据,但是内容类型依然是text/plain,而不是application/json,要返回这个格式的响应头,需要设置响应头才能实现:

//返回JSON格式数据\ngreeting:=Greeting{\n&34;,\n}\nmessage,_:=json.Marshal(greeting)\nw.Header().Set(&34;,&34;)\nw.Write(message)\n

重启HTTP服务器,并再次通过curl访问首页,就可以看到内容类型变成application/json了:

(全文完)

好了,文章到此结束,希望可以帮助到大家。

Published by

风君子

独自遨游何稽首 揭天掀地慰生平