外国做挂的网站是多少钱,网站关键词书写步骤,高端网名,手机网站模板psduniapp小程序开发实战系列#xff0c;完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中#xff0c;喜欢的可以点击收藏。 该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。
后台服务使用golang#xff0c;… uniapp小程序开发实战系列完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中喜欢的可以点击收藏。 该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。
后台服务使用golang因为它太适合做后台服务了。而且配合使用go-zero微服务框架不但强大还提供了好用的goctl工具自动生成接口框架代码让你写接口速度飞升。
下文以两个接口轮播图接口和豆瓣热门影视接口示例可以看到使用go-zero写服务接口是多么的简单。 为了示例和快速实现暂无后台管理界面。只实现后台接口。
轮播图接口返回json数据图片存储在腾讯云的COS对象存储服务作为图床使用。
豆瓣正在热映电影接口使用go-zero的httpc转发客户端请求到豆瓣v2的开源api服务https://api.douban.com/v2接口去请求数据。
go-zero 介绍
go-zero是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性经受了充分的实战检验。
go-zero 包含极简的 API 定义和生成工具 goctl可以根据定义的 api 文件一键生成 Go, iOS, Android, Kotlin, Dart, TypeScript, JavaScript 代码并可直接运行。
详细介绍go-zero 缩短从需求到上线的距离
github地址https://github.com/zeromicro/go-zero 文档介绍go-zero/readme-cn.md at master · zeromicro/go-zero · GitHub
goctl 工具安装
goctl 是 go-zero 的内置脚手架是提升开发效率的一大利器可以一键生成代码、文档、部署 k8s yaml、dockerfile 等。
# Go
GOPROXYhttps://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctllatest# For Mac
brew install goctl# docker for amd64 architecture
docker pull kevinwan/goctl
# run goctl like
docker run --rm -it -v pwd:/app kevinwan/goctl --help
由于我是在我的ubuntu20服务器上安装使用的所以选择了方式三。其实如果使用vscode, 则可以直接安装插件即可在vscode中搜索goctl插件。 在windows 上安装就不提了更简单了。
由于我的测试代码跑在腾讯云服务器上建议使用vscode远程连接的开发方式。在vscode上安装Remote - SSH插件非常好用使用方法VSCODE远程连接服务器远程开发。
goctl快速使用文档zero-doc/docs/zero/goctl-api.md at main · zeromicro/zero-doc · GitHub
快速开始
前提是具备golang环境和成功安装完成了goctl工具。
简易使用教程参加我的博客go-zero微服务框架入门教程_go-zero教程-CSDN博客
下面介绍下如何快速开始一个使用go-zero微服务框架的一个项目。
goctl api new greet
cd greet
go mod tidy
go run greet.go -f etc/greet-api.yaml
执行以上代码会自动创建工程目录greet,生成一些可以运行的模板文件。一个工程就创建完啦且执行go run 命令后台网关服务就已经启动起来啦默认端口8888这么简单。
接下来可以使用 curl命令测试一下接口
curl -i http://localhost:8888/from/you
api 文件定义了服务对外 HTTP 接口可参考 api 规范可以在 servicecontext.go 里面传递依赖给 logic比如 mysql, redis 等。
生成 api 服务
完成上面后只是一个空的服务接口如何增加自己的呢接下来详细介绍。其实就是写好api文件。api 文件定义了服务对外 HTTP 接口按它的api规范定义自己的接口文件。
我的api文件如下
syntax v1info (title: doc titledesc: imovie background service apiversion: 1.0
)type (//轮播图--应答SwiperData {id int json:idimageUrl string json:imageUrltitle string json:titledesc string json:description}SwiperResp {code int json:codemessage string json:messagedata []SwiperData json:data}//热门影视--请求HotMovieReq {start int json:startcount int json:countcity string json:city}//热门影视--应答HotItem {id string json:idcover string json:covertitle string json:titlerate int json:rate}HotMovieResp {code int json:codemessage string json:messagedata []HotItem json:datacount int json:countstart int json:starttotal int json:totaltitle string json:title}
)type Request {Name string path:name,optionsyou|me
}type Response {Message string json:message
}service imovie-api {doc (summary: imovie api)handler TestHandlerget /test/:name (Request) returns (Response)handler SwiperHandlerget /api/v1/swiperdata returns (SwiperResp)handler HotMovieHandlerpost /api/v1/hotmovie (HotMovieReq) returns (HotMovieResp)
}
由于我是在ubuntu服务器上以docker方式安装的goctl工具所以使用起来有点儿麻烦类似下面这样这么长一串
docker run --rm -it -v pwd:/app kevinwan/goctl --help
为了简单使用docker方式安装部署的goctl工具写了以下配置
docker-compose.yml version: 3services:goctl:image: kevinwan/goctlvolumes:- .:/appworking_dir: /app
于是后续再使用goctl命令变成了下面这种方式使用下述命令自动生成接口代码
sudo docker-compose run goctl api go -api go-imovie/imovie.api -dir go-imovie/
上述命令就根据 api 文件自动生成了服务接口代码。
参数含义介绍 业务代码编写
接下来开始关键的地方了业务接口的业务逻辑编写这部分主要在internal文件夹下的logic文件夹下实现。
轮播图接口
swiperlogic.go文件实现
package logicimport (contextimovie/internal/svcimovie/internal/typesgithub.com/zeromicro/go-zero/core/logx
)type SwiperLogic struct {logx.Loggerctx context.ContextsvcCtx *svc.ServiceContext
}var MyPic_ https://pic-1258623197.cos.ap-beijing.myqcloud.comfunc NewSwiperLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SwiperLogic {return SwiperLogic{Logger: logx.WithContext(ctx),ctx: ctx,svcCtx: svcCtx,}
}func (l *SwiperLogic) Swiper() (resp *types.SwiperResp, err error) {// todo: add your logic here and delete this line//var item types.SwiperDatavar responseData []types.SwiperDataitem1 : types.SwiperData{Id: 1,ImageUrl: MyPic_ /pic0/1.jpg,Title: 标题1,}item2 : types.SwiperData{Id: 2,ImageUrl: MyPic_ /pic0/2.jpg,Title: 标题2,}item3 : types.SwiperData{Id: 3,ImageUrl: MyPic_ /pic0/3.jpg,Title: 标题3,}responseData append(responseData, item1)responseData append(responseData, item2)responseData append(responseData, item3)resp types.SwiperResp{Code: 0,Message: success,Data: responseData,}return resp, nil
}热映电影接口
hotmovielogic.go文件实现实现客户端接口转发到豆瓣服务接口。
package logicimport (contextencoding/jsonionet/httpimovie/internal/svcimovie/internal/typesgithub.com/zeromicro/go-zero/core/logxgithub.com/zeromicro/go-zero/rest/httpc
)type HotMovieLogic struct {logx.Loggerctx context.ContextsvcCtx *svc.ServiceContext
}var Url_ https://api.douban.com/v2/movie/in_theaters
var ApiKey_ xxxxxxxxxx
var Referer_ https://images.weserv.nl/?urlfunc NewHotMovieLogic(ctx context.Context, svcCtx *svc.ServiceContext) *HotMovieLogic {return HotMovieLogic{Logger: logx.WithContext(ctx),ctx: ctx,svcCtx: svcCtx,}
}func (l *HotMovieLogic) HotMovie(req *types.HotMovieReq) (resp *types.HotMovieResp, err error) {// todo: add your logic here and delete this linetype Request struct {Req types.HotMovieReqApiKey string json:apikey}req_ : Request{Req: *req,ApiKey: ApiKey_,}l.Debug(req_)url : Url_res, err_ : httpc.Do(l.ctx, http.MethodPost, url, req_)if err_ ! nil {l.Error(err_)return nil, err_}defer res.Body.Close()body, err : io.ReadAll(res.Body)if err ! nil {l.Errorf(Failed to read response body:, err)return nil, err}//格式化输出json//var str bytes.Buffer//_ json.Indent(str, []byte(body), , )//l.Debugf(formated: , str.String())var keyVal map[string]interface{}err json.Unmarshal(body, keyVal)if err ! nil {l.Errorf(Failed to extract key value:, err)}//l.Debug(keyValue)var hot types.HotItemvar responseData []types.HotItemlist_, ok : keyVal[subjects].([]interface{})if ok {for _, item : range list_ {itemMap, ok : item.(map[string]interface{})if ok {//l.Debug(itemMap)hot.Id itemMap[id].(string)hot.Title itemMap[title].(string)tmp : itemMap[images].(map[string]interface{})hot.Cover Referer_ tmp[small].(string)hot.Rate int(itemMap[rating].(map[string]interface{})[average].(float64))}responseData append(responseData, hot)}}//t : reflect.TypeOf(keyVal[count])//l.Debugf(Type: %v\n, t)resp types.HotMovieResp{Code: 0,Message: res.Status,Data: responseData,Count: int(keyVal[count].(float64)),Start: int(keyVal[start].(float64)),Total: int(keyVal[total].(float64)),Title: keyVal[title].(string),}return resp, nil
}启动服务
启动服务很简单直接进入项目目录并执行 go run imovie.go即可。默认端口8888.
如果要更改配置可以进入项目目录下的etc文件夹找到imovie-api.yml文件修改。配置文件默认是yaml格式。日志的级别也可以在这里配置更改
Name: imovie-api
Host: 0.0.0.0
Port: 8000
Log:Level: debug关于YAML文件
YAMLYAML Aint Markup Language是一种简洁、易读、易写的用于数据序列化的数据交换格式。它常用于配置文件因为它比XML更简洁比JSON更易读写支持多行文本、注释等。
YAML的基本特点
1.大小写敏感
2.使用缩进表示层级关系不允许使用Tab键必须使用空格且相同层级的元素左侧对齐。
3.# 表示注释从这个字符开始直到行尾的内容都会被忽略。
YAML 文件示例
下面是一个简单的YAML文件示例展示了如何定义键值对、数组、嵌套结构以及使用注释。
# 这是一个YAML配置文件示例
server:# 服务器地址host: localhost# 服务器端口port: 8080# 数据库配置
database:# 数据库类型type: mysql# 数据库地址host: 127.0.0.1# 用户名username: root# 密码password: password123# 应用日志设置
logging:level: info # 日志级别# 日志文件路径file: /var/log/app.log# 开发者列表
developers:- name: 张三email: zhangsanexample.com- name: 李四email: lisiexample.com在这个示例中server、database、logging 和 developers 是顶层键每个键下可以有子键。 # 符号后面的内容是注释。
数组如 developers通过 - 符号标识每个元素并且每个元素都是一个映射键值对。
YAML文件在许多编程语言和框架中都有良好的支持用于配置应用程序的各种设置。
接口测试工具
推荐使用vscode的rest client插件编写以下测试文件名test.http
post http://175.178.126.10:8000/api/v1/hotmovie
Content-Type:application/json{start: 0,count: 1,city: 郑州
}### 下一项测试注意前面三个###分割 结果成功收到应答 豆瓣接口介绍
获取正在热映的电影
使用vscode的rest client插件测试接口
### Below is the code of douban.http,use vscode extension REST Client to send request.post https://api.douban.com/v2/movie/in_theaters
Content-Type:application/json{start: 0,count: 1,city: 郑州,apikey: xxxxxxxxxxx
}### Respondse{count: 1,start: 0,total: 43,subjects: [],title: \u6b63\u5728\u4e0a\u6620\u7684\u7535\u5f71-\u90d1\u5dde
}
或者使用curl命令测试接口
curl --location --request POST https://api.douban.com/v2/movie/in_theaters?city广州start0count1 --data-urlencode apikeyxxxxxxxxxxxxxx |python3 -m json.tool% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 1732 100 1693 100 39 4480 103 --:--:-- --:--:-- --:--:-- 4582
{count: 1,start: 0,total: 46,subjects: [{rating: {max: 10,average: 9.5,stars: 50,min: 0},genres: [\u7eaa\u5f55\u7247,\u97f3\u4e50],title: \u5742\u672c\u9f99\u4e00\uff1a\u6770\u4f5c,casts: [{alt: https://movie.douban.com/celebrity/1148641/,avatars: {small: https://img1.doubanio.com/view/personage/m/public/12ce4a9f67eac0cb029736ae87549dd0.jpg,large: https://img1.doubanio.com/view/personage/m/public/12ce4a9f67eac0cb029736ae87549dd0.jpg,medium: https://img1.doubanio.com/view/personage/m/public/12ce4a9f67eac0cb029736ae87549dd0.jpg},name: \u5742\u672c\u9f99\u4e00,id: 1148641}],collect_count: 19158,original_title: Ryuichi Sakamoto | Opus,subtype: movie,directors: [{alt: https://movie.douban.com/celebrity/1442776/,avatars: {small: https://img1.doubanio.com/view/celebrity/m/public/pXA5FFrGwJ94cel_avatar_uploaded1597077781.8.jpg,large: https://img1.doubanio.com/view/celebrity/m/public/pXA5FFrGwJ94cel_avatar_uploaded1597077781.8.jpg,medium: https://img1.doubanio.com/view/celebrity/m/public/pXA5FFrGwJ94cel_avatar_uploaded1597077781.8.jpg},name: \u7a7a\u97f3\u592e,id: 1442776}],year: 2023,images: {small: https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2907966076.jpg,large: https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2907966076.jpg,medium: https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2907966076.jpg},alt: https://movie.douban.com/subject/36491177/,id: 36491177}],title: \u6b63\u5728\u4e0a\u6620\u7684\u7535\u5f71-\u5e7f\u5dde
}
访问外部图片返回 403 Forbidden 错误问题
遇到提示{code:40310015,msg:referer uri is forbidden}表明豆瓣对图片资源的访问实施了Referer策略只允许特定来源referer的请求访问图片资源。当你直接在浏览器中输入图片链接能访问是因为浏览器的请求被视为合法的直接访问而前端应用尤其是Web应用发起请求时如果其域名不在豆瓣允许的Referer列表中就会被拒绝访问。
可以在前端页面头部添加一个meta
meta namereferrer contentno-referrer /
或者最简单的方式就是在img标签中增加
img src referrerPolicyno-referrer
各有优缺点吧某些旧版本或非主流浏览器可能不支持 referrer-policy。如果原始服务器严格限制Referer上述这种方法可能无效。
也可以借助Images.weserv.nl图片缓存网站帮我们解决这个问题。
images.weserv.nl 是一个免费的图片托管和缓存服务它可以用来间接访问受Referer限制的图片。这个服务会将原始图片URL作为参数传递然后返回一个新的URL这个新URL可以直接在前端使用而不需要担心Referer限制。
使用 images.weserv.nl 的步骤如下
替换图片URL将豆瓣的原始图片URL替换为 https://images.weserv.nl/?url原始图片URL。
在前端处理
// 图片防盗链问题解决
function attachImageUrl(srcUrl) {if (srcUrl ! undefined) {return srcUrl.replace(/http\w{0,1}:\/\/p/g, https://images.weserv.nl/?urlp)}
}
或者后台处理返回的图片url上做处理。
var Referer_ https://images.weserv.nl/?url var Referer_ https://images.weserv.nl/?urlvar keyVal map[string]interface{}err json.Unmarshal(body, keyVal)if err ! nil {l.Errorf(Failed to extract key value:, err)}//l.Debug(keyValue)var hot types.HotItemvar responseData []types.HotItemlist_, ok : keyVal[subjects].([]interface{})if ok {for _, item : range list_ {itemMap, ok : item.(map[string]interface{})if ok {//l.Debug(itemMap)hot.Id itemMap[id].(string)hot.Title itemMap[title].(string)tmp : itemMap[images].(map[string]interface{})hot.Cover Referer_ tmp[small].(string)hot.Rate int(itemMap[rating].(map[string]interface{})[average].(float64))}responseData append(responseData, hot)}}
由于豆瓣接口返回的json数据比较多且略显杂乱上述的json解析显得很麻烦。其实可以借助golang的三方库gjson处理这种格式的json数据。 gjson地址GitHub - tidwall/gjson: Get JSON values quickly - JSON parser for Go
图床服务推荐
我使用的是腾讯云上面的COS对象存储服务可以作为开发测试用。它提供试用和免费额度且提供免费域名直接可以https访问挺不错的。虽然github和gitee也能用作免费图床但是github访问慢而gitee直接停止page服务无法用了。
关于图床工具推荐使用PicList.
PicList是一款高效的云存储和图床平台管理工具在PicGo的基础上经过深度的二次开发不仅完整保留了PicGo的所有功能还增添了许多新的feature。例如相册支持同步云端删除文件内置图床额外添加了WebDav、本地图床和SFTP等。
PicList同时增加了完整的云存储管理功能包括云端目录查看、文件搜索、批量上传下载和删除文件复制多种格式文件链接和图片/markdown/文本/视频预览等另外还有更加强大的相册和多项功能新增或优化。
写在最后
最后附上完整后台golang源码https://download.csdn.net/download/qq8864/89401886
其他资源
0ab215a8b1977939201640fa14c66bab
https://go-zero.dev/docs/tutorials
https://zhuanlan.zhihu.com/p/570979109
https://github.com/zeromicro/go-zero?tabreadme-ov-file
https://github.com/zeromicro/zero-doc/blob/main/docs/zero/goctl-api.md
https://zhuanlan.zhihu.com/p/529462051
GitHub - tidwall/gjson: Get JSON values quickly - JSON parser for Go
https://www.jianshu.com/p/ef3fcf94295b
https://zhuanlan.zhihu.com/p/113500478
https://juejin.cn/post/6844903832040767496
https://blog.51cto.com/lanxf/5536521
uniapp中image不显示网络图片_uniapp image站外图片-CSDN博客
https://www.cnblogs.com/bigron/p/17334936.html
小白的最强保姆教学PicGo gitee Typora免费搭建属于个人的图床工具_picgocsdn-CSDN博客 文章转载自: http://www.morning.qclmz.cn.gov.cn.qclmz.cn http://www.morning.zpxwg.cn.gov.cn.zpxwg.cn http://www.morning.sbczr.cn.gov.cn.sbczr.cn http://www.morning.nrzkg.cn.gov.cn.nrzkg.cn http://www.morning.wtnwf.cn.gov.cn.wtnwf.cn http://www.morning.rwcw.cn.gov.cn.rwcw.cn http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.kwxr.cn.gov.cn.kwxr.cn http://www.morning.gbhsz.cn.gov.cn.gbhsz.cn http://www.morning.tpnxr.cn.gov.cn.tpnxr.cn http://www.morning.hilmwmu.cn.gov.cn.hilmwmu.cn http://www.morning.hwycs.cn.gov.cn.hwycs.cn http://www.morning.xrrbj.cn.gov.cn.xrrbj.cn http://www.morning.ffydh.cn.gov.cn.ffydh.cn http://www.morning.btqqh.cn.gov.cn.btqqh.cn http://www.morning.nrgdc.cn.gov.cn.nrgdc.cn http://www.morning.ndlww.cn.gov.cn.ndlww.cn http://www.morning.stmkm.cn.gov.cn.stmkm.cn http://www.morning.xhxsr.cn.gov.cn.xhxsr.cn http://www.morning.cffwm.cn.gov.cn.cffwm.cn http://www.morning.hclqy.cn.gov.cn.hclqy.cn http://www.morning.pjwml.cn.gov.cn.pjwml.cn http://www.morning.xhpnp.cn.gov.cn.xhpnp.cn http://www.morning.jlboyuan.cn.gov.cn.jlboyuan.cn http://www.morning.sbjhm.cn.gov.cn.sbjhm.cn http://www.morning.playmi.cn.gov.cn.playmi.cn http://www.morning.gqmhq.cn.gov.cn.gqmhq.cn http://www.morning.mstrb.cn.gov.cn.mstrb.cn http://www.morning.mzcsp.cn.gov.cn.mzcsp.cn http://www.morning.hmbxd.cn.gov.cn.hmbxd.cn http://www.morning.lyhrg.cn.gov.cn.lyhrg.cn http://www.morning.bmsqq.cn.gov.cn.bmsqq.cn http://www.morning.rttkl.cn.gov.cn.rttkl.cn http://www.morning.kjjbz.cn.gov.cn.kjjbz.cn http://www.morning.rydhq.cn.gov.cn.rydhq.cn http://www.morning.lkfsk.cn.gov.cn.lkfsk.cn http://www.morning.crqbt.cn.gov.cn.crqbt.cn http://www.morning.bnrnb.cn.gov.cn.bnrnb.cn http://www.morning.nnpwg.cn.gov.cn.nnpwg.cn http://www.morning.bwzzt.cn.gov.cn.bwzzt.cn http://www.morning.zdhnm.cn.gov.cn.zdhnm.cn http://www.morning.zbtfz.cn.gov.cn.zbtfz.cn http://www.morning.lfdmf.cn.gov.cn.lfdmf.cn http://www.morning.cnfxr.cn.gov.cn.cnfxr.cn http://www.morning.jrpmf.cn.gov.cn.jrpmf.cn http://www.morning.xnqjs.cn.gov.cn.xnqjs.cn http://www.morning.mqbsm.cn.gov.cn.mqbsm.cn http://www.morning.zztmk.cn.gov.cn.zztmk.cn http://www.morning.ljqd.cn.gov.cn.ljqd.cn http://www.morning.jbnss.cn.gov.cn.jbnss.cn http://www.morning.jgnjl.cn.gov.cn.jgnjl.cn http://www.morning.rxlck.cn.gov.cn.rxlck.cn http://www.morning.hnrpk.cn.gov.cn.hnrpk.cn http://www.morning.qkrz.cn.gov.cn.qkrz.cn http://www.morning.wlddq.cn.gov.cn.wlddq.cn http://www.morning.gpxbc.cn.gov.cn.gpxbc.cn http://www.morning.mkyny.cn.gov.cn.mkyny.cn http://www.morning.pzqnj.cn.gov.cn.pzqnj.cn http://www.morning.gwjqq.cn.gov.cn.gwjqq.cn http://www.morning.rgfx.cn.gov.cn.rgfx.cn http://www.morning.litao4.cn.gov.cn.litao4.cn http://www.morning.qkcyk.cn.gov.cn.qkcyk.cn http://www.morning.qqfcf.cn.gov.cn.qqfcf.cn http://www.morning.tynqy.cn.gov.cn.tynqy.cn http://www.morning.fyskq.cn.gov.cn.fyskq.cn http://www.morning.qkqzm.cn.gov.cn.qkqzm.cn http://www.morning.fglth.cn.gov.cn.fglth.cn http://www.morning.ktsth.cn.gov.cn.ktsth.cn http://www.morning.grqlc.cn.gov.cn.grqlc.cn http://www.morning.saletj.com.gov.cn.saletj.com http://www.morning.xbkcr.cn.gov.cn.xbkcr.cn http://www.morning.wnpps.cn.gov.cn.wnpps.cn http://www.morning.lmhh.cn.gov.cn.lmhh.cn http://www.morning.rydhq.cn.gov.cn.rydhq.cn http://www.morning.sqnrz.cn.gov.cn.sqnrz.cn http://www.morning.yckrm.cn.gov.cn.yckrm.cn http://www.morning.mbmtn.cn.gov.cn.mbmtn.cn http://www.morning.ldzss.cn.gov.cn.ldzss.cn http://www.morning.swzpx.cn.gov.cn.swzpx.cn http://www.morning.srgyj.cn.gov.cn.srgyj.cn