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

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

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

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1013閲覧

GO HTML 保存している画像が表示できない

mhk

総合スコア1

Go

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2022/10/21 23:49

編集2022/10/24 18:04

前提

Goでユーザーが登録した画像を表示するプログラムを作成しようと考えております。

├─app
||ーーviews
|  |ーーtemplates <-カレントフォルダ
|   |ーーーtop.html 

└─images

go.mod

1 github.com/google/uuid v1.3.0 // indirect 2 github.com/mattn/go-sqlite3 v1.14.15 // indirect 3 gopkg.in/go-ini/ini.v1 v1.67.0 // indirect

実現したいこと

  • 画像を表示させる

該当のソースコード

HTML

1{{define "content"}} 2<hr> 3{{ range . }} 4<!-- 構造体TodoのContentを表示 --> 5<img src="../../../images/{{ .Picture }}" width="20%"> 6<hr> 7{{end}}

Go

1<!-- 共通レイアウトを設定 --> 2{{define "layout"}} 3<!DOCTYPE html> 4<html lang="ja"> 5 6<head> 7 <meta charset="UTF-8"> 8 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 9 <title>SampleApp</title> 10 <link rel="stylesheet" href="/static/css/bootstrap.min.css"> 11 <link rel="stylesheet" href="/static/css/form.css"> 12</head> 13 14<body> 15 {{template "navbar"}} 16 <div class="container text-center"> 17 {{template "content" . }} 18 </div> 19 20</body> 21<script src="/static/js/jquery-3.6.1.min.js"></script> 22<script src="/static/js/bootstrap.bundle.min.js"></script> 23 24</html> 25{{end}}

view.go

1// 詳細ページの表示 2func view(w http.ResponseWriter, r *http.Request, id int) { 3 4 c, err := models.GetCircle(id) 5 if err != nil { 6 log.Println(err) 7 } 8 generateHTML(w, c, "layout", "public_navbar", "circle/view") 9}

generateHTML.go

1func generateHTML(w http.ResponseWriter, data interface{}, filenames ...string) { 2 var files []string 3 for _, file := range filenames { 4 files = append(files, fmt.Sprintf("app/views/templates/%s.html", file)) 5 } 6 templates := template.Must(template.ParseFiles(files...)) 7 templates.ExecuteTemplate(w, "layout", data) 8}ateHTML.go 9

signup_circle.go

startmainserver.go

1func StartMainServer() error { 2 // http.FileServerはハンドラーを返す。 3 // http.Dirは必ずFileServerの引数にする。 4 // Dirで静的ファイルを読み込む。 5 files := http.FileServer(http.Dir(config.Config.Static)) 6 http.Handle("/static/", http.StripPrefix("/static/", files))

config.go

1 Static: cfg.Section("web").Key("static").String(),

config.ini

1static = app/views

試したこと

  • VScodeのGo Liveを試したときは、以下のコードで画像が表示されました。
<img src="./pokemon.jpg" width="20%">

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

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

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

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

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

m.ts10806

2022/10/21 23:53

>パス指定は合っていると思います。 現状だとファイル構成も提示されてないので「合ってないんでしょう」としか言えないのですが、 どのような配置になってるのでしょうか。ファイル構成を提示してください。 サーバーサイドのフレームワークであれば静的リソースの配置については指定や読み込む機能があるはずなので、あまり直にパスを書くべきではないとも思います。 Webルート以下に静的リソースを置かないフレームワークもありますから。 利用しているフレームワークも提示されたほうが良いです。
nobonobo

2022/10/22 03:28

ファイル構成と標準net/httpで作られていることは分かりましたが、 「実行時のカレントフォルダ」がどこなのかと「Goのコード(抜粋でもよい)」を示してほしい。
nobonobo

2022/10/22 11:10

あとは静的ファイルをどうやってサーブしているかの該当コードが欲しいです。
mhk

2022/10/22 11:35

お世話になっております。 私の質問力不足でご迷惑をおかけして申し訳ございません。 どのようにしてサーブしているかの該当コードを載せました。
nobonobo

2022/10/22 13:21 編集

そのカレントフォルダtemplatesの下に「images/アップロードファイル名」でファイルを作ろうとしてしまいます。 そんなフォルダは無いのでエラーになる様な気がします。エラーにならずにアップロードはできていますか?
nobonobo

2022/10/22 13:18

あと、アップロード済みのファイルを読み込んで返す部分の実装が見当たりません。
nobonobo

2022/10/22 13:20

/static配下のファイル群をサーブしている実装はありますか?
mhk

2022/10/22 13:46

お世話になっております。 実行すると、imagesフォルダの中にアップロードされます。
nobonobo

2022/10/22 13:57

そこが期待通りに動くということはappやimagesの親フォルダがカレントフォルダになっているのでは? あと/static配下をどうやってサーブしているかなども開示されなければ回答は難しいです。
mhk

2022/10/22 22:10

nobonobo様、お世話になっております。 /static配下をどのようにサーブしているか載せました。 どうぞよろしくお願いいたします。
nobonobo

2022/10/23 02:39

カレントフォルダをtemplatesフォルダ基準と誤解されていませんか? os.Createに渡される相対パスは「カレントフォルダパス」を基準として処理されます。 Goのプロセスを起動した時のフォルダです。 プログラム内ではos.Getwd()にてカレントフォルダは取得できますので確認ください。
nobonobo

2022/10/23 02:55 編集

テンプレート(HTML)に書く内容に基準となるパスはURLをベースとします。 osパッケージによるファイル操作は「カレントフォルダ」をベースとします。 これらは基準が異なるので双方それぞれの基準を意識してコードを書くことが必要です。 コードを見る限りなにか相対パスの扱いに誤解があるように見えます。 「URLのパスツリー」と「ファイルシステムのパスツリー」は別物で誰かが紐づけてあげる必要があります。 /static/というURLを./static/というフォルダに紐づけているコードがあるので、/static/以下のURLは./static/フォルダ以下とマッチするようになりブラウザからファイルシステムが見えるということです。 imagesフォルダは./staticフォルダ配下ではなさそうに見えるのでimagesフォルダ配下を別途URL側に紐づける実装が必要です。 (この辺りはっきりしたいのならstaticフォルダをフォルダツリーに追記して欲しい) その実装はstaticフォルダ同様「http.FileServerを使うハンドラ」か「パスを解釈してos.Openしてその内容をレスポンスとして返すハンドラ」という内容がメジャーです。
guest

回答1

0

ベストアンサー

極力シンプルな画像一覧&画像アップロードサンプルを提示します。参考に。

https://go.dev/play/p/UzyfgLazIbk

go:main.go

1package main 2 3import ( 4 "html/template" 5 "io" 6 "log" 7 "net/http" 8 "os" 9 "path/filepath" 10) 11 12const Images = "./images" 13 14var topPage = template.Must(template.New("").Parse(`<!DOCTYPE html> 15<body> 16<form action="/upload" method="post" enctype="multipart/form-data" > 17<div> 18 <input type="file" name="upload"> 19</div> 20<div> 21 <input type="submit" value="送信する"> 22</div> 23</form> 24{{range .}} 25<figure> 26<img src="/images/{{.Name}}" width="120px"/> 27<figcaption>{{.Name}}</figcaption> 28</figure> 29{{end}} 30</body> 31`)) 32 33func upload(w http.ResponseWriter, r *http.Request) { 34 if r.Method != "POST" { 35 http.Error(w, "method not allowed: "+r.Method, http.StatusMethodNotAllowed) 36 return 37 } 38 if err := r.ParseForm(); err != nil { 39 http.Error(w, err.Error(), http.StatusInternalServerError) 40 return 41 } 42 fileSrc, fileHeader, err := r.FormFile("upload") 43 if err != nil { 44 log.Print(err) 45 http.Error(w, err.Error(), http.StatusInternalServerError) 46 return 47 } 48 defer fileSrc.Close() 49 uploadedFileName := fileHeader.Filename 50 imagePath := filepath.Join(Images, uploadedFileName) 51 fileDest, err := os.Create(imagePath) 52 if err != nil { 53 http.Error(w, err.Error(), http.StatusInternalServerError) 54 return 55 } 56 //ファイルをクローズしておく 57 defer fileDest.Close() 58 if _, err := io.Copy(fileDest, fileSrc); err != nil { 59 log.Print(err) 60 http.Error(w, err.Error(), http.StatusInternalServerError) 61 return 62 } 63 http.Redirect(w, r, "/", http.StatusSeeOther) 64} 65 66func index(w http.ResponseWriter, r *http.Request) { 67 files, err := os.ReadDir(Images) 68 if err != nil { 69 http.Error(w, "readdir failed", http.StatusInternalServerError) 70 return 71 } 72 if err := topPage.Execute(w, files); err != nil { 73 http.Error(w, err.Error(), http.StatusInternalServerError) 74 return 75 } 76} 77 78func main() { 79 if _, err := os.Stat(Images); os.IsNotExist(err) { 80 if err := os.MkdirAll(Images, 0755); err != nil { 81 log.Fatal(err) 82 } 83 } 84 http.HandleFunc("/", index) 85 http.HandleFunc("/upload", upload) 86 http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir(Images)))) 87 if err := http.ListenAndServe(":8080", nil); err != nil { 88 log.Fatal(err) 89 } 90}

投稿2022/10/23 13:09

編集2022/10/23 13:11
nobonobo

総合スコア3367

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

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

nobonobo

2022/10/24 09:04 編集

あ、http.ServeFileを使う方がもっとシンプルでしたあとで修正します! あ、違った。FileServerであってますね。
mhk

2022/10/24 07:59

nobonobo様ありがとうございました。 私の質問力不足でご迷惑をおかけしました。 私の勉強不足でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問