3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

個人的GoとVueの繋げ方(CORS,FileServer)

Posted at

今回はVueとGolangをつなげる際に死にかけたところを書くよ

#作成時
結構前に短縮URLのバックエンドを作成してホッとしていました。
が、今度はフロントエンドの作成というわけですよ

初めてフロントエンドに挑戦ということでVue.jsを使ってましたが...
####まぁ、初めて触ったらなんのこっちゃで分からんがな ←なにやってんだ
直接Vueのページに見ても何書いてるか分からない
なんとなく1画面をサンプル見ながら作ってみてた
VueだとSPAとかが作れるって?
ページたくさん作らずにできるなら便利そうだな...
って思いながらrouterで接続先を設定とかカチカチ...

とりあえず手探りでやって、どうにかフロントエンドのWeb画面はできました。
Golangとは違って1.5ヶ月かかりましたね...

###さて問題がここからだ
GolangとVueをつなごうかと思って
まずはaxiosを見つけて導入してみました。
axiosでGetメソッドやPostメソッドを作って
データの取得や新規作成などができるし、非常にわかりやすいので採用!!
エンドポイントを指定して、受け取り方を設定して動かすぜ!!

###て、思ってたんですよ...CORSに出会うまでは

localhostで動かそうとするとね、バックエンドとフロントエンドが噛み合わないんですよ
どうやらWebブラウザでは、Webサイトが持つ情報が別の悪意あるサイトに使われないためにSame-Origin Policyというものがあるのです。
悪意あるサイトに使われないために制限をかけているのは良いのですが、信頼しているものまで制限をかけやがるのですよ
別に私は悪意なんてないんですがね...

そこで出会ったのはCORSですよ

##CORSって?
CORSはあるWebサイトから別のWebサイトへのアクセスを許可するものです
これを作らないとGolangとVue.jsの間に橋がかからないのです

Golang(go-chi使ってます)では

main.go
func main() {

	r := chi.NewRouter()
    r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(60 * time.Second))
	r.Use(Cors)
}
func Cors(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := appengine.NewContext(r)
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
		w.Header().Set("ExposedHeaders", "Link")
		w.Header().Set("Access-Control-Allow-Credentials", "true")
		log.Infof(ctx, "Should set headers")
		if r.Method == "OPTIONS" {
			log.Infof(ctx, "Should return for OPTIONS")
			return
		}
		next.ServeHTTP(w, r)
	})
}

を書き足してあげればいけるはず
MethodやHeaderは自分で調整ということで

Vue.jsではconfigで調整しましょう

index.html
proxy: {
      
      './': {
        target: 'http://localhost:8080',
        ws: true,
        changeOrigin: true
      }
     },

これでlocalhostでつなぎました。

よっしゃ繋いだぜ、ひゃっほいで終わったら良かったのですが、
ここからが本当の地獄の始まりでした

##Golangでlocalhost立ち上げると真っ白です
繋ぐことがわかったのでVue側で色んなモジュール見つけては便利にしようと色々試して「ええやん...これ」と思ってました。
vue-good-tableを使ってみたり、bootstrap-bueでデザインの良いボタンつけてみたりしてみたんですよ

いざそれでGolangで開くとですね...真っ白...
幻影でも見てたかのように真っ白でした。
エラーを見るとcss,jsなどなど読み取れねーよと

これを解決する方法はhttp.FileServer,http.StripPrefixが鍵となりました
これはVueで作った静的なページを返すというものです。
これを使ってjs,css,vue-good-tableなどを読んであげます
でもこれだけだと宣言しただけなのでこれを使ってあげます
http.StripPrefixで指定したパスをhttp.FileServerが捜索するURLを取り除きましょう

main.go
var vueTemplate *template.Template

func main() {
	r.Get("/", VueHandler)
    r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(middleware.Logger)
	r.Use(middleware.Recoverer)
	r.Use(middleware.Timeout(60 * time.Second))
	r.Use(Cors)

	//Vue.jsで作成したの静的ページを返す
	//これを使用しないとGolangでVueのパッケージなどが表示されない
	static := http.FileServer(http.Dir("./(your-file-name)/dist/static"))
	table := http.FileServer(http.Dir("./(your-file-name)/node_modules/vue-good-table"))
	css := http.FileServer(http.Dir("./(your-file-name)/dist/static/css"))
	js := http.FileServer(http.Dir("./(your-file-name)/dist/static/js"))
	public := http.FileServer(http.Dir("./(your-file-name)/public"))
	src := http.FileServer(http.Dir("./(your-file-name)/src"))

	//http.StripPrefix()は、第1引数に指定したパスを、http.FileServer()が捜索するURLから取り除く。
	http.Handle("/static/", http.StripPrefix("/static/", static))
	http.Handle("/vue-good-table/", http.StripPrefix("/vue-good-table/", table))
	http.Handle("/css/", http.StripPrefix("/css/", css))
	http.Handle("/js/", http.StripPrefix("/js/", js))
	http.Handle("/public/", http.StripPrefix("/public/", public))
	http.Handle("/src/", http.StripPrefix("/src/", src))
	http.Handle("/", r)
	appengine.Main()
}

//Vue.jsのindex.htmlを読み込み ブラウザで表示する処理
func VueHandler(w http.ResponseWriter, r *http.Request) {
	vueTemplate = template.Must(template.ParseFiles("./(your-file-name)/dist/index.html"))
	err := vueTemplate.ExecuteTemplate(w, "index.html", siteKey)
	if err != nil {
		log.Errorf(appengine.NewContext(r), err.Error())
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	return
}

以上です

これに気づかずにずっと沼ってしまった私ですが、どうにか脱出できました。
参考程度に書きましたが、大丈夫かな?
ではでは(^^)

##参考URL
http://www.tohoho-web.com/ex/same-origin-policy.html Some-Origin-Policy
https://qiita.com/mochizukikotaro/items/6b72ad595db8a6b5514f GOやPHPのCORSがより詳しいです
https://www.kabanoki.net/3230/ Vue-Good-Tableの参考です
https://blog.y-yuki.net/entry/2017/05/19/163000 http.StripPrefixの参考です

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?