ais05
@ais05

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ターミナルでは表示されるのに、一部ブラウザには出力されない

Q&A

Closed

プログラム初心者です
分かるかたいらっしゃいましたら教えていただけると幸いです

やりたいこと

ディレクトリ内のjpgをすべてブラウザに表示させるプログラムを書きたい

問題

ターミナルではきちんと表示されるのに、ブラウザには反映されない

環境

OS ubuntuServer 22.04
WEBServ nginx 1.24.0
Python 3.10.6

ssiは有効にして、htmlからmain要素に呼び込んでいます

ディレクトリ構成
(問題のページのみ書いています)

root
 ┠ app/
 ┃  ┗ contents/
 ┃    ┗ 002/
 ┃      ┠ include/
 ┃      ┃  ┗ python
 ┃      ┃    ┗ timeln.py
 ┃      ┠ date/
 ┃      ┃  ┗ photo/
 ┃      ┃    ┠ 1.jpg
 ┃      ┃    ┠ ~.jpg
 ┃      ┃    ┠ 5.jpg
 ┃      ┠ index.html

index.html

省略
        <main>
        <!--ここからメイン要素------------------------------------------------------------------------------------------------------------------------------------>
            
            <div class="container">
                <!--#include virtual="/app/contents/002/include/python/timeln.py" -->
            </div>

        <!--ここまでメイン要素------------------------------------------------------------------------------------------------------------------------------------>
        </main>
省略

timeln.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import cgi, glob, pathlib, cgitb, sys, io

ROOT ='/app/contents/002/date/photo/'


cgitb.enable()
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')


print('Content-type: text/html\n')

print('<p>なんでここは表示されるのに</p>')

photo = pathlib.Path(f'.{ROOT}').glob('*.jpg')
for i in photo:
    print(f'<img src="{ROOT}{i.name}" class="article-header">')


print('<p>画像は表示されないねん</p>')

出力結果ブラウザ

なんでここは表示されるのに
画像は表示されないねん


出力結果ターミナル(vscodeでF5押すとでてくるところ)

user@servername:/webROOT/$ /usr/bin/env /bin/python3 /home/user/.local/share/code-server/extensions/ms-python.python-2023.8.0-universal/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 38741 -- /webROOT/app/contents/002/include/python/timeln.py 
Content-type: text/html

<p>なんでここは表示されるのに</p>
<img src="/app/contents/002/date/photo/1.jpg" class="article-header">
<img src="/app/contents/002/date/photo/3.jpg" class="article-header">
<img src="/app/contents/002/date/photo/4.jpg" class="article-header">
<img src="/app/contents/002/date/photo/2.jpg" class="article-header">
<p>画像は表示されないねん</p>

わかる方いらっしゃいましたら教えていただけると幸いです

1

2Answer

nginx.confの記載が無いので推測になりますが中身に

nginx.conf
root /app/contents/002;

のように/app/contents/002がパブリックディレクトリとして指定され、これかこれより下位のディレクトリがhttpとしてアクセス可能な範囲であるため

ブラウザでhttp://<ドメイン>/date/photo/1.jpgを開くと表示される可能性はあります。
(念のために申し上げておきますが<ドメイン>の部分は差し替えて下さい)

1Like

Comments

  1. @ais05

    Questioner

    ご回答ありがとうございます
    パスをフルパスではなく、ウェブルートから指定していたのが原因でした

ROOT ='/app/contents/002/date/photo/'

print('Content-type: text/html')
print('Content-Length: ???')
print('\n')

print(f'<img src="{ROOT}{i.name}" class="article-header">')

先ずはwebサーバが正常にファイルをダウンロードできるか?確認してはどうでしょう?

http://servername:80/webROOT/app/contents/002/date/photo/xxx.jpg

0Like

Comments

  1. @ais05

    Questioner

    回答ありがとうございます。
    説明不足で申し訳ありません。
    画像のパスは問題なくブラウザからアクセスできます。また、ターミナルで出力された画像のhtmlコードをコピーして、手動でhtmlに貼りつけてみたりもしましたが問題なく表示されます。
    nginxのlogも何も問題なく、ただほんとに画像の部分だけ表示されない状態です。

  2. print('Content-Length: ???')
    print('\n')
    これかも?

    Content-Lengthの指定がないので、クライアント側はブラウザの判断でbodyの終端を解釈します。

    例えば、print('<p>なんでここは表示されるのに</p>')のあたりで終わりと判断されます。

    photo = pathlib.Path(f'.{ROOT}').glob('*.jpg')
    body = ""
    for i in photo:
        body += f'<img src="{ROOT}{i.name}" class="article-header">'
    head = 'Content-Length: ' + str(len(body))
    print(head + "¥n" + body)
    

    このコードはbodyを先に作成して,Content-Length: を計算したのち、一気にapache等へ渡す方式です。

    一部ブラウザとはedge,chromeでしょうか?

    そもそも、print('Content-type: text/html')やprint('Content-Length: ???')は要らないのでは?
    レンダリング(SSI)なので

  3. @ais05

    Questioner

    これです

    <img src="/app/contents/002/date/photo/1.jpg" class="article-header">
    <img src="/app/contents/002/date/photo/3.jpg" class="article-header">
    <img src="/app/contents/002/date/photo/4.jpg" class="article-header">
    <img src="/app/contents/002/date/photo/2.jpg" class="article-header">
    
  4. print('\n')
    これかも?

    <img src="/app/contents/002/date/photo/2.jpg" class="article-header">

    はhtmlに生成されている

    http://servername:80/webROOT/app/contents/002/date/photo/2.jpg
    ではダウンロードできない?
    http://servername:80/app/contents/002/date/photo/2.jpg
    でダウンロードできる?
    で宜しいでしょうか?

    wget か curlでレスポンスヘッダーを確認したいですね?

  5. print('Content-Length: ???')
    の指定か?
    print('Content-type: text/html\n')
    が邪魔なのでは?

  6. http://servername:80/app/contents/002/include/python/timeln.py
    正しく、Content-Length:を指定すれば表示できるとおもいます。

    cgiはヘッダーが必要ですが、レンダリング(SSI)はhtmlに埋め込むのでヘッダーは不要です。apache側でヘッダーが付与されます。

  7. @ais05

    Questioner

    ご回答ありがとうございます
    パスをフルパスではなく、ウェブルートから指定していたのが原因でした
    何度も回答ありがとうございましたm(_ _)m

Your answer might help someone💌