简体   繁体   中英

Redirect requests for static files

I'm trying to serve a static html file, and this file has script tags that point to other resources. I want to serve the html file from one directory but then redirect requests for assets to another directory. This is how I'm setting it up now:

// server.go
import (
    "fmt"
    "html/template"
    "log"
    "net/http"
    "path"
    "time"
)

func handle(w http.ResponseWriter, r *http.Request) {
    lp := path.Join("./", "index.html")
    fmt.Println(lp)
    tmpl, err := template.ParseFiles(lp)
    if err != nil {
        log.Fatal(err)
    }
    tmpl.ExecuteTemplate(w, "index", nil)
}

func main() {
    fs := http.FileServer(http.Dir("../../app_assets/"))
    http.Handle("/assets", fs)
    http.HandleFunc("/static/", handle)

    fmt.Println("Go Server listening on port 8000")
    http.ListenAndServe(":8000", nil)
}

Here is my template:

<!-- index.html -->
{{define "index"}}
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="assets/css/libs.css" type="text/css" />
</head>

<body>
<script type="text/javascript" src="assets/js/libs.js"></script>

<h1> Hello </h1>
</body>
</html>
{{end}}

I'm able to serve the index file from localhost:8000/static/ , but asset requests are not going to the assets folder two levels up ( ../../ ). What am I doing wrong?

NOTE:

I'm getting this error in the console when libs.js is loaded:

Uncaught SyntaxError: Unexpected token <

This leads me to believe that the request for the libs.js file is being redirected to the html markup.

How is this happening?

NOTE 2:

When I browse the result of the request for libs.js , I see the html markup. Even after using StripPrefix as advised below. What am I doing wrong?

So I know it's a bit confusing, but you want to change fs := http.FileServer(http.Dir("../../assets/")) to be fs := http.FileServer(http.Dir("../.."))

The reason is that the path for "assets" is already specified in the request so as you have it, it is really pointing to ../../assets/assets/*

Hope that helps!

oh and just to prevent another error, that Handle() functions should be written with a trailing slash in the path. I almost forgot to catch that.

EDIT

To adjust my answer for your other need (using some sort of redirect) you'd have to use the http.StripPrefix handler https://golang.org/pkg/net/http/#StripPrefix

For your use case you would prepare your server with the following code:

fs := http.FileServer(http.Dir("../../app_assets"))
http.Handle("/assets/", http.StripPrefix("/assets/", fs))

This lets you do url rewrites for file system serving.

In your html when you specify the src attributes of your css and js you have src="assets/js/libs.js" . This makes those files to be requested relative to the current path. So the request goes to http://localhost:8000/static/assets/js/libs.js .

Since this has the /static prefix it will be handled by your /static handler and hence the html file is served.

To make it go to /assets handler, specify the src with a / prefixed.

<script type="text/javascript" src="/assets/js/libs.js"></script>

Now the server will look for the file at ../../app_assets/assets/js/libs.js .

If you want it to be ../../app_assets/js/libs.js , you can use StripPrefix to take out the assets part from the url in the server.

fs := http.StripPrefix("/assets/", http.FileServer(http.Dir("../../app_assets/")))
http.Handle("/assets/", fs)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM