亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么我的腳本讀取在我的 HTML 中鏈接的文件,而在 GoLang 中使用

為什么我的腳本讀取在我的 HTML 中鏈接的文件,而在 GoLang 中使用

Go
慕碼人8056858 2022-11-23 15:57:44
我有一個 GoLang 腳本,用于根據瀏覽器中的輸入查詢動態構建網頁,如下所示http://localhost:8000/blog/post#,該post#部分用于識別要解析到我創建的 HTML 模板中的 JSON 數據文件;例如,如果我把它從我的文件中http://localhost:8000/blog/post1創建一個文件。目前,我的腳本在運行時允許我在瀏覽器中加載單個頁面,然后它退出并在我的終端標準輸出日志中顯示錯誤:index.htmlpost1.json2022/03/18 00:32:02 error: open jsofun.css.json: no such file or directoryexit status 1這是我當前的腳本:package mainimport (    "encoding/json"    "html/template"    "io/ioutil"    "log"    "net/http"    "os")func blogHandler(w http.ResponseWriter, r *http.Request) {    blogstr := r.URL.Path[len("/blog/"):]    blogstr = blogstr + ".json"    // read the file in locally    json_file, err := ioutil.ReadFile(blogstr)    if err != nil {        log.Fatal("error: ", err)    }    // define a data structure    type BlogPost struct {        // In order to see these elements later, these fields must be exported        // this means capitalized naming and the json field identified at the end        Title       string `json:"title"`        Timestamp   string `json:"timestamp"`        Main        string `json:"main"`        ContentInfo string `json:"content_info"`    }    // json data    var obj BlogPost    err = json.Unmarshal(json_file, &obj)    if err != nil {        log.Fatal("error: ", err)    }    tmpl, err := template.ParseFiles("./blogtemplate.html")    HTMLfile, err := os.Create("index.html")    if err != nil {        log.Fatal(err)    }    defer HTMLfile.Close()    tmpl.Execute(HTMLfile, obj)    http.ServeFile(w, r, "./index.html")}func main() {    http.HandleFunc("/blog/", blogHandler)    log.Fatal(http.ListenAndServe(":8080", nil))}我已經完成了一些基本的調試,并確定問題出在以下幾行:json_file, err := ioutil.ReadFile(blogstr)    if err != nil {        log.Fatal("error: ", err)    }令我困惑的是為什么 ioutil.ReadFile 也試圖讀取我的 HTML 中鏈接的文件?瀏覽器不應該處理該鏈接而不是我的處理程序嗎?作為參考,這是我jsofun.css鏈接文件的 HTML;我的控制臺輸出中引用的錯誤顯示我的腳本jsofun.css.json在調用期間嘗試訪問此文件ioutil.ReadFile:
查看完整描述

2 回答

?
繁星coding

TA貢獻1797條經驗 獲得超4個贊

您的 Go 服務器設置為僅提供/blog/路徑服務,它通過執行blogHandler. 在您的 Go 服務器中沒有其他任何東西被設置為提供諸如 css、js 或圖像文件之類的資產。


對于這樣的事情,您通常需要FileServer在單獨的路徑上注冊一個單獨的處理程序。例子:


func main() {

    http.HandleFunc("/blog/", blogHandler)

    // To serve a directory on disk (/path/to/assets/on/my/computer)

    // under an alternate URL path (/assets/), use StripPrefix to

    // modify the request URL's path before the FileServer sees it:

    http.Handle("/assets/", http.StripPrefix("/assets/",

        http.FileServer(http.Dir("/path/to/assets/on/my/computer"))))

    log.Fatal(http.ListenAndServe(":8080", nil))

}

您需要修復的另一件事是 HTML 中那些資產字段的鏈接,它們應該是絕對的,而不是相對的。


...

<link rel="stylesheet" href="/assets/jsofun.css"></style>

...

<script src="/assets/jsofun.js">

以上當然只有在資產位于/path/to/assets/on/my/computer目錄中時才有效,例如


/path/to/assets/on/my/computer

├── jsofun.css

└── jsofun.js

您blogHandler不必要地為每個請求創建一個新文件而不刪除它,這有可能很快將您的磁盤填滿到其最大容量。要提供模板,您不需要創建新文件,而是可以直接將模板執行到http.ResposeWriter. 還建議只解析一次模板,尤其是在生產代碼中,以避免不必要的資源浪費:


type BlogPost struct {

    Title       string `json:"title"`

    Timestamp   string `json:"timestamp"`

    Main        string `json:"main"`

    ContentInfo string `json:"content_info"`

}


var blogTemplate = template.Must(template.ParseFiles("./blogtemplate.html"))


func blogHandler(w http.ResponseWriter, r *http.Request) {

    blogstr := r.URL.Path[len("/blog/"):] + ".json"


    f, err := os.Open(blogstr)

    if err != nil {

        http.Error(w, err.Error(), http.StatusNotFound)

        return

    }

    defer f.Close()


    var post BlogPost

    if err := json.NewDecoder(f).Decode(&post); err != nil {

        http.Error(w, err.Error(), http.StatusInternalServerError)

        return

    }

    if err := blogTemplate.Execute(w, post); err != nil {

        log.Println(err)

    }

}


查看完整回答
反對 回復 2022-11-23
?
呼喚遠方

TA貢獻1856條經驗 獲得超11個贊

讓我們研究一下當您請求時會發生什么http://localhost:8000/blog/post#。

瀏覽器請求頁面;您的代碼成功構建并返回一些html- 這將包括:

<link rel="stylesheet" href="./jsofun.css"></style>

瀏覽器接收并處理 HTML;作為該過程的一部分,它要求css上述內容。現在原始請求在文件夾中,/blog/post#因此./jsofun.css變為http://localhost:8000/blog/jsofun.css.

當您的 go 應用程序收到此請求blogHandler時將被調用(由于請求路徑);它剝離/blog/然后添加.json以獲取文件名jsofun.css.json。然后您嘗試打開此文件并收到錯誤消息,因為它不存在。

有幾種方法可以解決這個問題;更改要使用的模板<link rel="stylesheet" href="/jsofun.css"></style>可能是一個開始(但我不知道jsofun.css存儲在哪里,并且您沒有顯示任何可用于該文件的代碼)。我認為還值得注意的是,您不必index.html在磁盤上創建文件(除非有其他原因需要這樣做)。

(請參閱 mkopriva 對其他問題和進一步步驟的回答 - 在發布該答案時輸入此內容已經進行了一半,并且覺得演練可能仍然有用)。


查看完整回答
反對 回復 2022-11-23
  • 2 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號