<p>I've got my SPA (React running with multiple routes. eg, "localhost:3000/", and you can click on a link to route to "localhost:3000/about" but if you go directly to "localhost:3000/about" in the browser, you get 404'd. How can I get Go to accept JUST "/", routing to Index, and everything after that is still part of "/", routing the SPA instead of trying to load a page hosted at "/about"? Tried multiple ways, I can't seem to get anything to work.</p>
<hr/>**评论:**<br/><br/>HarveyKandola: <pre><p>This is how you would do it with Gorilla Mux (we do the same thing with EmberJS):</p>
<pre><code>router := mux.NewRouter()
router.HandleFunc("/{rest:.*}", emberHandler)
func emberHandler(w http.ResponseWriter, r *http.Request) {
emberView := template.Must(template.ParseFiles("index.html"))
if err := emberView.Execute(w, nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
</code></pre>
<p>Does this help?</p></pre>natdm: <pre><p>Any idea on how to do it with the default libs, or <a href="https://github.com/julienschmidt/httprouter" rel="nofollow">https://github.com/julienschmidt/httprouter</a> ? </p></pre>HarveyKandola: <pre><p>See this: <a href="https://golang.org/pkg/net/http/#example_ServeMux_Handle" rel="nofollow">https://golang.org/pkg/net/http/#example_ServeMux_Handle</a></p></pre>elithrar_: <pre><p>Render the template outside the handler; re-parsing on every request is pretty expensive. </p></pre>stroborobo: <pre><p>Ok, let's make this simple :) I guess you're using an http.FileSystem to serve all your files.</p>
<pre><code>package static
import (
"net/http"
"os"
"path"
)
func Handler() http.Handler {
return http.FileServer(&indexWrapper{assets})
}
type indexWrapper struct {
assets http.FileSystem
}
func (i *indexWrapper) Open(name string) (http.File, error) {
ret, err := i.assets.Open(name)
if !os.IsNotExist(err) || path.Ext(name) != "" {
return ret, err
}
return i.assets.Open("index.html")
}
</code></pre></pre>natdm: <pre><p>Better idea of what I'm trying to accomplish.</p>
<pre><code> package main
import (
"log"
"net/http"
"github.com/julienschmidt/httprouter"
"html/template"
)
func main() {
router := httprouter.New()
router.GET("/public/bundle.js", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
http.ServeFile(w, r, "client/public/bundle.js")
})
router.GET("/about", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
tmpl := template.Must(template.ParseFiles("client/index.html"))
tmpl.Execute(w, nil)
})
router.GET("/", func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
tmpl := template.Must(template.ParseFiles("client/index.html"))
tmpl.Execute(w, nil)
})
log.Fatal(http.ListenAndServe(":3000", router))
}
</code></pre>
<p>/ and /about are pages on the SPA, where Bundle is my main package. I'd rather serve anything under /public and anything with an actual route go to the SPA. </p></pre>thepciet: <pre><p>Do you need the third party router? With the default by handling '/' you get all requests to '/' and anything in that subtree (like '/about').</p>
<pre><code>http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method != "GET" {...}
if r.URL.Path == "/" {...}
else if r.URL.Path == "/about" {...}
...
tmpl.Execute(w, nil)
})
</code></pre></pre>denmaradi: <pre><p>Why do have same handler for both "/" and "/about"? Both needs to have their own separate handlers. </p>
<p>When someone goes to localhost/about, "about" handler needs to respond not "/".</p>
<p>Additionally your js app can send special headers that you can parse on your middleware or something to distinguish between SPA call and normal call.</p></pre>stroborobo: <pre><p>Just curious, why using templates if you've got everything on frontend side with React?</p></pre>natdm: <pre><p>I don't have to. I could just serve the index.html. Was just cycling through multiple ideas.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传