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

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

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

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

HTML

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

解決済

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

mhk
mhk

総合スコア1

Go

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

HTML

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

1回答

0グッド

0クリップ

665閲覧

投稿2022/10/21 23:49

編集2022/10/22 22:09

前提

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%">

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/10/22 01:01依頼された後にこの質問は修正されています

こちらの質問が他のユーザーから「プログラミングに関係のない質問」という指摘を受けました。

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してその内容をレスポンスとして返すハンドラ」という内容がメジャーです。

回答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

総合スコア3259

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

nobonobo

2022/10/24 09:04 編集

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

2022/10/24 07:59

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

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

Go

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

HTML

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