質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

Q&A

解決済

1回答

2148閲覧

Go言語のhttp.HandleFunc が正しく動作しないことがある

退会済みユーザー

退会済みユーザー

総合スコア0

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

1グッド

1クリップ

投稿2020/05/29 04:40

編集2020/05/29 13:42

前提・実現したいこと

Go言語でwebアプリを作っています.新しい関数を追加した時に,何もおこらないことがあったので質問します.

dockerでgo(:8080)とmysql(:3360)のコンテナが動いており,そこでgoのアプリが動いています.

発生している問題・エラーメッセージ

main.go

1package main 2 3import ( 4 "log" 5 "net/http" 6 7 "./auth" 8 "./webpages" 9 10 _ "github.com/go-sql-driver/mysql" 11) 12 13func main() { 14 15 16 http.HandleFunc("/", webpages.TopPage) 17 18 http.HandleFunc("/logout", auth.Logout) 19 20 // http.HandleFunc("/test", webpages.Test) 21 log.Println("Listening on :8080...") 22 http.ListenAndServe(":80", nil) 23} 24

webpages.TopPage,auth.Logout,webpages.Testはともに空の関数.

localhost:8080/logoutにアクセスすると,localhost:8080/に飛ばされてしまう.
(このとき,とくにエラーは出ない)
localhost:8080/testにアクセスすると,正常に動作する.

試したこと

元々,関数の中には処理が書いてありましたが,処理を全てコメントアウトしても改善しませんでした.

追記

パッケージが分かれていることが問題かと思い,webpagesの中にLogout関数を定義したところ,やはり同様の症状が確認されました.

func Logout(w http.ResponseWriter , r *http.Request){ fmt.Println("hoge") auth.Logout(w,r) }

hogeの出力もありませんでした

func Logout(w http.ResponseWriter , r *http.Request){ fmt.Println("auth.Logout") }

auth.Logoutの処理を追記しました.

アドレスを/logoutから/logoutpageに変更したら改善しました.

補足情報(FW/ツールのバージョンなど)

go version go1.14.2 darwin/amd64

Client: Docker Engine - Community Version: 19.03.8 API version: 1.40 Go version: go1.12.17 Git commit: afacb8b Built: Wed Mar 11 01:21:11 2020 OS/Arch: darwin/amd64 Experimental: false
DrqYuto👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

実際にリッスンしているアドレスに":80"が書かれていますのでlocalhost:8080を開いても
Goのプロセスにブラウザからのリクエストが届かないかもしれません。

ハンドラの内容を空にするのではなくlog.Println(req)とでも書けばリクエストが来たかどうかはわかります。

また、相対パスインポートはソース公開するような実装では非推奨なのでご注意ください。

追記

手元の環境では例示のソースコードを以下のコマンドにて起動した場合、
意図通りのハンドラが呼ばれることを確認できました。

sh

1docker run -it --rm -p 8080:80 -v $PWD:/app -w /app golang:alpine go run .

気をつけなければいけないのは、ブラウザは"/favicon.ico"をリクエストすることです。
(例示のソースの場合webpages.TopPageのハンドラが呼び出されます)
このあたりはブラウザのデバッガを参考にしてください。

あとはブラウザキャッシュにリダイレクトするようなコンテンツが残っている場合などもありますので
キャッシュの削除をお試しください。

Goの公開ライブラリを見て貰えばわかりますが、相対パスインポートを使っているものはほとんど見られないはずです。
なぜなら、Goのimport記述はnode.jsでいうところのpackage.jsonの機能を兼ねているからです。
依存解決を正確に行うために公開先のURLを伴うパス名を記述するのがGoの推奨です。
go getがで依存解決またはアプリのインストールができることを「go-gettable」と言いますが、
Goによるライブラリやアプリケーションがgo-gettableであることは多くのGoユーザーが期待するものです。
相対パスインポートを利用してしまうとgo-gettableではなくなってしまいます。

なので例示のコードもGo-Moduleをつかってなんらかの有効なimportパスを付与することをお勧めします。

sh

1go mod init github.com/ユーザー名/アプリケーション名

としておいて、
以下のようにインポートパスを書くと良いでしょう。

go

1import( 2 "github.com/ユーザー名/アプリケーション名/auth" 3 "github.com/ユーザー名/アプリケーション名/webpages" 4)

投稿2020/05/29 07:28

編集2020/05/30 04:25
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/29 10:47

回答ありがとうございます. 書き忘れていましたが,dockerの80番ポートをlocalhostの8080番ポートに割り当てているのでこれで問題ないはずです. また,ご指摘いただいた通りどの関数が呼び出されたか確認できるようにしたところ,/testの場合は`fmt.Println("Test")`が実行されましたが /logout では何も実行されず,localhost:8080に戻ってしまいました. 最後に,Go言語は経験が浅く,相対パスインポートが非推奨な理由がわからないのでよろしければそちらにつきましてもご説明の程よろしくお願いします.
d_tutuz

2020/05/29 13:12

authのパッケージでおそらく宣言している /logout でどのような処理を実施しているか記載しないと分からないかと思います。
退会済みユーザー

退会済みユーザー

2020/05/29 13:43

追記しましたので,ご確認よろしくお願いします.
退会済みユーザー

退会済みユーザー

2020/05/30 08:38

favicon.icoに対するハンドラを定義したら解決しました.回答ありがとうございました. また,このソースコードは公開するものではありませんが,今後そういうものを制作する場合は気をつけたいと思います.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問