因为我是学Java的,主要做web开发,所以看了点go的基础知识后,就试着把以前的demo用go实现以下,而且go web开发非常简便只要几行代码,就能实现简单http服务器,今天主要写一下用net/http包模拟客户端发送请求实现百度推送(实时)。
开始
项目结构
.
├── static
| ├── css
| └── layer
├── views
| └── index.html
└── main.go
main.go
package main
import (
"fmt"
"html/template"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
)
func main() {
http.HandleFunc("/", index)
http.HandleFunc("/send", bdSend)
//处理静态文件
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
err := http.ListenAndServe(":80", nil)
if err != nil {
log.Fatal(err)
}
}
//首页
func index(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
t, err := template.ParseFiles("views/index.html")
if err != nil {
log.Fatal(err)
}
t.Execute(w, nil)
}
}
//推送
func bdSend(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
request(w, r)
}
}
//模拟http客户端post发送请求
func request(w http.ResponseWriter, r *http.Request) {
//先解析form
err := r.ParseForm()
if err != nil {
log.Fatal(err)
}
//请求地址
var apiURL string
switch r.Form["oper"][0] {
case "post":
apiURL = "http://data.zz.baidu.com/urls"
case "update":
apiURL = "http://data.zz.baidu.com/update"
case "del":
apiURL = "http://data.zz.baidu.com/del"
}
//初始化参数
param := url.Values{}
//配置请求参数,方法内部已处理urlencode问题,中文参数可以直接传参
param.Set("site", r.Form["site"][0])
param.Set("token", r.Form["token"][0])
var URL *url.URL
URL, err = url.Parse(apiURL)
if err != nil {
fmt.Printf("解析url错误:\r\n%v", err)
}
//如果参数中有中文参数,这个方法会进行URLEncode
URL.RawQuery = param.Encode()
client := &http.Client{}
req, _ := http.NewRequest("POST", URL.String(), strings.NewReader(r.Form["sendURL"][0]))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
//req.Header.Set("User-Agent", "curl/7.12.1")
//req.Header.Set("Host", "data.zz.baidu.com")
//发送请求
resp, err := client.Do(req)
//注意关闭resp.Body
defer resp.Body.Close()
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("请求失败,错误信息:\r\n%v", err)
} else {
//var returns map[string]interface{}
//json.Unmarshal(data, &returns)
//data, err = json.Marshal(returns)
//将返回的json数据返给客户端浏览器
fmt.Fprintln(w, string(data))
}
}
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
<title>百度主动推送(实时)</title>
<LINK rel="Bookmark" href="/static/favicon.ico">
<LINK rel="Shortcut Icon" href="/static/favicon.ico" />
<!-- Bootstrap -->
<link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/style.css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body class="bg-body">
<div class="container text-center bg">
<h1>百度主动推送(实时)</h1>
<form class="form-horizontal" id="form" >
<div class="form-group form-group-lg">
<div class="col-sm-8 col-sm-offset-2">
<select class="form-control" id="oper" name="oper">
<option value="post">推送数据</option>
<option value="update">更新数据</option>
<option value="del">删除数据</option>
</select>
</div>
</div>
<div class="form-group form-group-lg">
<div class="col-sm-8 col-sm-offset-2">
<input type="tel" class="form-control" id="site" name="site" placeholder="要推送内容的网站,例如:www.example.com" required >
</div>
</div>
<div class="form-group form-group-lg">
<div class="col-sm-8 col-sm-offset-2">
<input type="tel" class="form-control" id="token" name="token" placeholder="百度站长平台秘钥,例如:ZD4V6EK2QNpzwill" required >
</div>
</div>
<div class="form-group form-group-lg">
<div class="col-sm-8 col-sm-offset-2">
<textarea class="form-control" name="sendURL" rows="8" placeholder="网址之间要换行,例如:
http://www.example/abc.hml
http://www.example/bcd.html" ></textarea>
</div>
</div>
<div class="form-group form-group-lg">
<div class="col-sm-8 col-sm-offset-2">
<button type="button" class="btn btn-success btn-lg btn-block" onclick="ajaxSub()">推送</button>
</div>
</div>
<h3>© 2016 powered by <a href="http://willxue.top" target="_blank">willxue</a></h3>
</form>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="/static/layer/layer.js"></script>
<script type="text/javascript">
function ajaxSub(){
$.post("/send", $("#form").serialize(), function(result){
if (result.indexOf("Exception")>0) {
layer.alert("请确认站点和token是否匹配",{title: "错误",icon:2});
} else {
var data = JSON.parse(result);
if (result.indexOf("success")>0) {
layer.alert("成功推送了:"+data.success+" 个<br/>今天还能推送:"+data.remain+" 个<br/>不是本站而未处理的url列表: "+data.not_same_site+"<br/>不合法的url:"+data.not_valid,{icon:1});
} else{
layer.alert("推送失败了,错误码:"+data.error+"<br/>错误描述:"+data.message,{title: "错误",icon:2});
}
}
});
}
</script>
</div>
</body>
</html>
Demo
在线demo部署在daocloud http://gobaidu.daoapp.io/