douru5373 2016-03-12 02:41
浏览 10
已采纳

在浏览器中显示Go App

I wrote an app that makes a request to an API and gets a JSON response. When I run the app it displays the json in the terminal.

go run main.go

I want to make this run in the browser and I found this, which allowed me to print a string to the browser.

     func handler(w http.ResponseWriter, r *http.Request) {
       fmt.Fprintf(w, "This is a string")
   }

Then in main

http.HandleFunc("/", handler) 
log.Fatal(http.ListenAndServe("localhost:8000", nil))

Now that I have a string being printed to the screen and I have a json response coming from the api I am using, how can I add the json response to the browser instead of the string?

Would it be best to put the response into a string then just bring it to the browser?

Currently I am printing the json response to the terminal like this,

type Payload struct {
        Page    int
        Results []Data 
}

type Data struct {
        PosterPath       string  `json:"poster_path"`
        Adult            bool    `json:"adult"`
        Overview         string  `json:"overview"`
        ReleaseDate      string  `json:"release_date"`
        GenreIds         []int   `json:"genre_ids"`
        Id               int     `json:"id"`
        OriginalTitle    string  `json:"original_title"`
        OriginalLanguage string  `json:"original_language"`
        Title            string  `json:"title"`
        BackdropPath     string  `json:"backdrop_path"`
        Popularity       float64 `json:"popularity"`
        VoteCount        int     `json:"vote_count"`
        Video            bool    `json:"video"`
        VoteAverage      float64 `json:"vote_average"`
}

Then inside main() I do this,

    for i := 0; i < len(p.Results); i++ {
            fmt.Println(
            ImgUrl+p.Results[i].PosterPath, "
", p.Results[i].Adult,
            p.Results[i].Overview, "
", p.Results[i].ReleaseDate,
            p.Results[i].GenreIds, "
", p.Results[i].Id,
            p.Results[i].OriginalTitle, "
", p.Results[i].OriginalLanguage,
            p.Results[i].Title, "
", ImgUrl+p.Results[i].BackdropPath,
            p.Results[i].Popularity, "
", p.Results[i].VoteCount,
            p.Results[i].Video, "
", p.Results[i].VoteAverage,
            )

What would be the Go way to do this for building web applications? My end goal here is to take user input and recreate my api call based on the information they provide.

  • 写回答

1条回答 默认 最新

  • dongsisui7562 2016-03-12 02:59
    关注

    If you are fine with directly sending the response from the API to your users then use io.Copy. You can check if the api request was successful before relaying it to the users and send an error if it did not.

    Some APIs send information in headers like how you are doing with the rate limiting. So you can check headers as well before relaying.

    func handler(w http.ResponseWriter, r *http.Request) {
        resp, err := http.Get("http://jsonplaceholder.typicode.com/posts") // your request to the api
    
        w.Header().Set("Content-Type", "application/javascript")
    
        if err == nil && resp.StatusCode == http.StatusOK {
            io.Copy(w, resp.Body)
        } else {
            json.NewEncoder(w).Encode(err)
        }
    }
    

    This avoids making any new allocations on your app.

    If you want to send your clients html as stated in comments, use the html/template package.

    You can of course prepare a html string manually and send it to the clients. But I think its obvious that using templates makes the code cleaner and maintainable. It also provides autoescaping.

    For example following would render the Overview section of each of your Results from the Payload p

    func handler(w http.ResponseWriter, r *http.Request) {
        // Make your api call and prepare the `Payload` object (from your example in the question)
    
        for i := 0; i < len(p.Results); i++ {
           fmt.Println(p.Results[i].Overview) // Prints to your terminal
        }
    
        // Following sends same information as above to the browser as html
    
        t, err := template.New("foo").Parse(`
          {{define "T"}}
            <html><ul>{{range .Results}}<li>{{.Overview}}</li>{{end}}</ul></html>
          {{end}}`)
        err = t.ExecuteTemplate(w, "T", p) // This writes the client response
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)
  • ¥20 matlab yalmip kkt 双层优化问题