GO语言(二十)编写Web应用程序(中)
编辑页面
wiki需要能编辑页面。让我们创建两个新的处理程序:一个命名editHandler为显示编辑页面表单,另一个命名saveHandler为保存通过表单输入的数据。
首先,我们将它们添加到main():funcmain(){http。HandleFunc(view,viewHandler)http。HandleFunc(edit,editHandler)http。HandleFunc(save,saveHandler)log。Fatal(http。ListenAndServe(:8080,nil))}
editHandler函数加载页面(或者,如果它不存在,则创建一个空Page结构),并显示一个HTML表单。funceditHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(edit):〕p,err:loadPage(title)iferr!nil{pPage{Title:title}}fmt。Fprintf(w,h1Editingsh1,p。Title,p。Title,p。Body)}
这个函数可以正常工作,但所有硬编码的HTML都很丑陋。当然,还有更好的方法。
htmltemplate包
该htmltemplate包是Go标准库的一部分。我们可以使用htmltemplate将HTML保存在单独的文件中,允许我们更改编辑页面的布局,而无需修改底层Go代码。
首先,我们必须添加htmltemplate到导入列表中。我们也不会再使用fmt了,所以我们必须删除它。import(htmltemplateosnethttp)
让我们创建一个包含HTML表单的模板文件。打开一个名为的新文件edit。html,并添加以下行:h1Editing{{。Title}}h1
修改editHandler以使用模板,而不是硬编码的HTML:funceditHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(edit):〕p,err:loadPage(title)iferr!nil{pPage{Title:title}}t,:template。ParseFiles(edit。html)t。Execute(w,p)}
template。ParseFiles函数将读取内容edit。html并返回一个template。Template。
t。Execute方法执行模板,将生成的HTML写入http。ResponseWriter。。Title和。Body标识符指的是p。Title和p。Body。
模板指令用双花括号括起来。该printfs。Body指令是一个函数调用,它以字符串而不是字节流的形式输出,与fmt。Printf一致。htmltemplate包有助于确保模板操作仅生成安全且外观正确的HTML。例如,它会自动转义任何大于号(),将其替换为gt,以确保用户数据不会破坏HTML表单。
由于我们现在正在使用模板,让我们为viewHandler调用创建一个模板view。html:h1{{。Title}}h1p〔edit〕{{printfs。Body}}
相应修改viewHandler:funcviewHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(view):〕p,:loadPage(title)t,:template。ParseFiles(view。html)t。Execute(w,p)}
请注意,我们在两个处理程序中使用了几乎完全相同的模板代码。让我们通过将模板代码移动到它自己的函数来删除这个重复:funcrenderTemplate(whttp。ResponseWriter,tmplstring,pPage){t,:template。ParseFiles(tmpl。html)t。Execute(w,p)}
并修改处理程序以使用该功能:funcviewHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(view):〕p,:loadPage(title)renderTemplate(w,view,p)}funceditHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(edit):〕p,err:loadPage(title)iferr!nil{pPage{Title:title}}renderTemplate(w,edit,p)}
如果我们在main中注释掉我们未实现的保存处理程序的注册,我们可以再次构建和测试我们的程序。
处理不存在的页面
如果你访问viewAPageThatDoesntExistloadPage呢?您将看到一个包含HTML的页面。这是因为它忽略了错误返回值,并继续尝试填写没有数据的模板。相反,如果请求的页面不存在,它应该将客户端重定向到编辑页面,以便可以创建内容:funcviewHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(view):〕p,err:loadPage(title)iferr!nil{http。Redirect(w,r,edittitle,http。StatusFound)return}renderTemplate(w,view,p)}
http。Redirect函数向HTTP响应添加HTTP状态代码http。StatusFound(302)和一个新的位置。保存页面
saveHandler函数将处理位于编辑页面上的表单的提交。取消main注释中的相关行后,让我们实现处理程序:funcsaveHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(save):〕body:r。FormValue(body)p:Page{Title:title,Body:〔〕byte(body)}p。save()http。Redirect(w,r,viewtitle,http。StatusFound)}
页面标题(在URL中提供)和表单的唯一字段Body存储在一个新的Page。然后调用该save()方法将数据写入文件,并将客户端重定向到view页面。
返回的值FormValue是string类型。我们必须将该值转换为〔〕byte,然后才能将其放入Page结构中。我们用〔〕byte(body)来执行转换。
错误处理
在我们的程序中有几个地方会忽略错误。这是不好的做法,尤其是因为当确实发生错误时,程序会出现意外行为。更好的解决方案是处理错误并将错误消息返回给用户。这样,如果出现问题,服务器将完全按照我们想要的方式运行,并且可以通知用户。
首先,让我们处理以下错误renderTemplate:funcrenderTemplate(whttp。ResponseWriter,tmplstring,pPage){t,err:template。ParseFiles(tmpl。html)iferr!nil{http。Error(w,err。Error(),http。StatusInternalServerError)return}errt。Execute(w,p)iferr!nil{http。Error(w,err。Error(),http。StatusInternalServerError)}}
http。Error函数发送指定的HTTP响应代码(在本例中为内部服务器错误)和错误消息。
现在让我们修复saveHandler:funcsaveHandler(whttp。ResponseWriter,rhttp。Request){title:r。URL。Path〔len(save):〕body:r。FormValue(body)p:Page{Title:title,Body:〔〕byte(body)}err:p。save()iferr!nil{http。Error(w,err。Error(),http。StatusInternalServerError)return}http。Redirect(w,r,viewtitle,http。StatusFound)}
p。save()期间发生的任何错误都会报告给用户。
有什么提升厨房使用体验感的好物推荐吗?谢邀唯美食与爱不可辜负,厨房是一道道美食诞生的地方,也是居家收获幸福的小空间。少不了烟火气的厨房,自然也常伴随着一些使用不便之处令人糟心。想要拥有舒适的厨房体验往往需要用……
OPPO新发布会封神成为手机行业顶级大厂8月19日OPPO发布了未来影像技术,整个发布会看完,我觉得OPPO真的是过于低调了。新一代RGBW首先这RGBW捕光传感器也不是什么黑科技了,最早的RGBW镜头C……
央行全面推广移动支付应用e公司讯,3月29日,人民银行召开支付结算工作电视电话会议。会议要求,2019年深化支付领域改革开放,加快支付清算市场结构优化升级,推动支付产业高质量发展。要处理好当前与长远、……
特斯拉手机Model会再次改变我们的生活吗?特斯拉要出手机了,这让很多人充满了期待,甚至有人猜测特斯拉手机会再次改变我们的生活。马斯克发布的产品每一次都是颠覆性的,这次特斯拉手机model,会像当年苹果手机一样颠覆……
联发科再出新品,6nm工艺加持,定位中高端手机同质化的今天,越来越多的厂商走向了自研芯片的道路,事实也证明,要想进军高端就必须要拥有核心技术,否则在各种配置几乎一样的今天,只能与其他友商打价格战了。如今小米、vi……
独角兽公司校招来了顺联动力,娱乐社交电商领域的开拓者火热的夏天虽然要过去了,但一场人才争夺战却在持续升温。日前,互联网大厂掀起新一轮抢人大战。百度、阿里、腾讯、美团、字节、小米等各大互联网企业接连登场,不约而同的打出了史上……
快速搭建基于HTTPS的本地开发环境奇技指南本文作者李松峰,资深技术图书译者,翻译出版过40余部技术及交互设计专著,现任360奇舞团高级前端开发工程师,360前端技术委员会委员、W3CAC代表。本文首……
手机可拆卸电池的设计为什么被抛弃?要知道,资本家打着改进的旗号,以赚取更多的利润的技能是无穷尽的,包括且不限于:取消附赠充电器、取消耳机孔、取消卡针、手机配件加密、不支持存储卡扩展、系统不断升级。。。……
喜欢贴地驾驶,这几款即将上市的纯电轿车该怎么选?撰文陈辉对于想买纯电轿车的消费者来说,接下来一段时间将会是一个非常好的时期,因为陆续将会有多款纯电轿车上市。虽说选择更丰富了,但同时也不免挑花眼。那么即将上市的这几……
SpringCloud2022。0。0M1发布需Java17各位小伙伴们,复工第一天,DD祝大家新年快乐!这个新年真的是好好休息了一下,文章也没有更,新闻也没怎么看。所以,新年第一篇就先带大家一起回顾下春节期间的一些新动态。从Sprin……
微信打开这3个设置,可提升流畅度和安全性,老人也需要学会分享生活小妙招,共享科技新生活!大家好,欢迎来到今天的知识分享!我是你们的好朋友小俊!我们在使用微信的时候,经常会觉得微信用起来非常卡顿,其实我们只需要设置一个开关,就可……
七夕节你还在送口红香水吗?七夕给心爱的TA送什么礼物呢?口红?香水?拜托,不要这么直男了,好吗?今年七夕,为生活在数码时代的TA送上一份怎样的礼物呢,我们为你做了这些选择,你能选上吗?无线桌面音箱……