HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
1102
chellcat画像などローカル上にあるファイルをhspsockを通してブラウザに表示させたい10解決


chellcat

リンク

2021/11/2(Tue) 12:30:32|NO.94275

過去のスレッド「ローカルサーバー的なやつの作成」(http://hsp.tv/play/pforum.php?mode=pastwch&num=84888)
で hspsock を用いてHSP側で用意したHTMLをブラウザで表示させられてますが、
画像などローカル上にあるファイルをHTMLを通してブラウザに表示させることは可能でしょうか?
実行ファイルと同じフォルダやカレントディレクトリにtest.jpgを置いて
 put+="<img src=\"test.jpg\" >\n" 

を追加して試したりしてみましたが、うまくいきません。
put+="<img src=\"http://hsp.tv/images/bbs/mascot2s.jpg\" >\n"
のように、インターネット上に公開されている画像はうまく表示できました。

HTMLの知識もあまりなく申し訳ないですが、色々試してもhspsockを使って
ローカルファイルを表示させる方法わからなかったので教えていただければありがたいです。



この記事に返信する


zrs90(5さい)

リンク

2021/11/2(Tue) 13:36:34|NO.94277

HTMLでローカルにある画像を表示する
...で検索して見て下さい。

hspsock自体使った事のないど素人の
投稿なので、間違ってたら申し訳ないです。
(何故かhsp関係のワードを含めると
上手く検索出来なかった。)



ベイン

リンク

2021/11/2(Tue) 14:36:06|NO.94278

参考記事:
"HTTP の概要 - HTTP | MDN"
https://developer.mozilla.org/ja/docs/Web/HTTP/Overview#http_flow

sockgetでリクエストの1行目を取り出して
GET / ... だったら従来通りhtmlを送る、
GET /test.jpg ... だったらtest.jpgを送る (ただしContent-Typeはimage/jpeg)、
というふうにしたらできると思います



chellcat

リンク

2021/11/3(Wed) 15:49:17|NO.94284

皆さん早速のご返信ありがとうございます。
階層に置けば読み込んでくれるというわけではなくブラウザで表示させるには思ってたより複雑なんですね。

なるほど。画像要求でも度々通信しているんですね。
GET / ... だったら従来通りhtmlを送る、
GET /test.jpg だったらtest.jpgを送る (ただしContent-Typeはimage/jpeg)
とても参考になりました。リクエストやレスポンスの方法で試してみたいと思います。
HTTPの参考になるサイトも案内頂きありがとうございます。

画像を送る点で、こちらのサイトなどを参考にbloadで画像を読み込んで最後にデータ付け足して送信してみたのですが表示できませんでした。
https://stackoverflow.com/questions/14728125/how-do-i-send-an-image-over-http-protocol-in-c

pcbnet2のサンプルを使用させて頂き試してみたのですが、画像の指定先が間違っているのでしょうか?


#include "pcbnet2.as" screen 0,,1000 filename="test.jpg" sdim Response1,2500 notesel Response1 noteadd "HTTP/1.1 200 OK" noteadd "Content-Type: text/html;charset=shift-jis" ;文字コードをついでに指定 noteadd "Connection: Close\n" ;HTTPヘッダーの最後は改行x2 noteadd "<!DOCTYPE html>" noteadd "<html>" noteadd "<head>" noteadd "<title>helloHTML</title>" noteadd "</head>" noteadd "<body>" noteadd "Hello" noteadd "<img src=\"http://hsp.tv/images/bbs/mascot2s.jpg\">"//ネット上に公開されている画像 noteadd "<img src=\""+filename+"\">"//表示させたいローカルファイル noteadd "</body>" noteadd "</html>" exist filename filesize=strsize if filesize!-1 { sdim testIMG,filesize bload filename,testIMG,filesize,0 mes "LOAD IMG>>"+filesize+"byte" } sdim head notesel head noteadd "HTTP/1.1 200 OK" noteadd "Content-Type: image/jpeg" noteadd "Content-Lenth:"+filesize headsize = varsize(head) sdim Response2,filesize+headsize Response2 += head Response2 += testIMG bufsize = varsize(put2) mes"=============================" mes Response1 mes"=============================" mes Response2 mes"=============================" title "hspsock Server.as互換サーバー" port=999 mes "ポート "+port+" で接続を待っています..." tcpmake lis,port if stat : dialog "ソケットの作成に失敗しました。",1 : end onexit *bye *top repeat tcpwait lis if stat : break wait 10 loop tcpaccept soc,lis if stat : goto *top sdim s,1024 tcpinfo s,soc color 0,0,0 :mes "接続しました。("+s+")" sdim REQ_LINE,256 tcpgetl REQ_LINE,1024,soc color 0,0,255 :mes REQ_LINE sdim REQ,256 tcprecv REQ,0,256,soc wait 100 if instr(REQ_LINE,0,filename) = -1 { tcpput Response1,soc color 255,0,0 :mes "HTML REQUEST>>" }else{ tcpput Response2,soc color 0,255,0 :mes "IMG REQUEST>>" } tcpshut soc ;// 通信終了を通知する repeat tcpfail soc if stat=2:break ;// 切断が完了するのを待つ wait 1 loop tcpclose soc ;// ソケットを閉じる goto *top *bye tcpclose lis end



ベイン

リンク

2021/11/3(Wed) 18:17:58|NO.94289

おおよそ合っています。以下の点を改善したところ、私の環境では動きました

40行目あたり:
画像のレスポンスヘッダーの最後に、2つ目の改行が抜けています


; noteadd "Content-Lenth:"+filesize noteadd "Content-Lenth:"+filesize + "\n"

また、文字列の長さはstrlenで取得します


; headsize = varsize(head) headsize = strlen(head)

少し下にあるResponse2を計算するところですが
testIMG は文字列ではなくバイナリデータなので、+= では連結できません
バイナリデータのコピーにはmemcpy命令を使います


; Response2 += testIMG memcpy Response2, testIMG, filesize, headsize

この記事が文字列に関して詳しく説明しています
"HSP3 文字列のひみつ(TIPS)"
https://www.onionsoft.net/hsp/v36/doclib/hsp3str.htm

これを読むと、逆に
文字列ではないバイナリデータを文字列用の命令に渡したとき
問題が起こる理由が分かると思います

画像のようなバイナリデータは、データの途中に0であるバイトが含まれます
文字列として扱うと、そこでデータの終わりとみなされてしまって
正常に動かないというわけです

最後に、レスポンスを返すところ
先ほどと同様にResponse2はバイナリデータなので、
tcpsend命令を使います


; tcpput Response2,soc tcpsend Response2, 0, headsize + filesize, soc



chellcat

リンク

2021/11/3(Wed) 18:32:53|NO.94290

firefoxの調査でネットワークモニターを見たところ画像70biteしか送れていなかったので
tcpputからtcpsendに変更したところ転送量から画像データは送れているみたいですが依然として表示させられませんでした。


#include "pcbnet2.as" screen 0,,1000 filename="test.jpg" sdim Response1,2500 notesel Response1 noteadd "HTTP/1.1 200 OK" noteadd "Content-Type: text/html;charset=shift-jis" ;文字コードをついでに指定 noteadd "Connection: Close\n" ;HTTPヘッダーの最後は改行x2 noteadd "<!DOCTYPE html>" noteadd "<html>" noteadd "<head>" noteadd "<title>helloHTML</title>" noteadd "</head>" noteadd "<body>" noteadd "Hello" noteadd "<img src=\"http://hsp.tv/images/bbs/mascot2s.jpg\">" noteadd "<img src=\""+filename+"\">" noteadd "</body>" noteadd "</html>" exist filename filesize=strsize if filesize!-1 { sdim testIMG,filesize bload filename,testIMG,filesize,0 mes "LOAD IMG>>"+filesize+"byte" bsave "0.jpg",testIMG,filesize } sdim head notesel head noteadd "HTTP/1.1 200 OK" noteadd "Accept-Ranges: bytes" noteadd "Connection: keep-alive" noteadd "Content-Length: "+filesize noteadd "Content-Type: image/jpeg" noteadd "Server: localhost" noteadd "\n" headsize = varsize(head) sdim Response2,filesize+headsize Response2 += head Response2 += testIMG bufsize = varsize(Response2) mes"=============================" mes Response1 mes"=============================" mes Response2 mes"=============================" title "hspsock Server.as互換サーバー" port=999 mes "ポート "+port+" で接続を待っています..." tcpmake lis,port if stat : dialog "ソケットの作成に失敗しました。",1 : end onexit *bye *top repeat tcpwait lis if stat : break wait 10 loop tcpaccept soc,lis if stat : goto *top sdim s,1024 tcpinfo s,soc color 0,0,0 :mes "接続しました。("+s+")" sdim REQ_LINE,1024 tcpgetl REQ_LINE,1024,soc color 0,0,255 :mes REQ_LINE sdim REQ,1024 tcprecv REQ,0,1024,soc wait 10 if instr(REQ_LINE,0,filename) = -1 { tcpput Response1,soc color 255,0,0 :mes "HTML REQUEST>>" }else{ tcpsend Response2,0,bufsize,soc color 0,255,0 :mes "IMG REQUEST>>" } tcpshut soc ;// 通信終了を通知する repeat tcpfail soc if stat=2:break ;// 切断が完了するのを待つ wait 1 loop tcpclose soc ;// ソケットを閉じる goto *top *bye tcpclose lis end



chellcat

リンク

2021/11/3(Wed) 18:41:41|NO.94291

ベインさんとても分かりやすく教えていただきありがとうございます!

ご指摘いただいた修正箇所を修正して試してみたいと思います。

そうだったんですね。データについてわかっていなかったのでとても参考になりました。
教えていただいた記事も参考に学ばせて頂きます。
ありがとうございました。



chellcat

リンク

2021/11/3(Wed) 18:48:36|NO.94292

ありがとうございます。
教えていただいた通り修正したところこちらでも画像表示確認できました。



#include "pcbnet2.as" screen 0,,1000 filename="test.jpg" sdim Response1,2500 notesel Response1 noteadd "HTTP/1.1 200 OK" noteadd "Content-Type: text/html;charset=shift-jis" ;文字コードをついでに指定 noteadd "Connection: Close\n" ;HTTPヘッダーの最後は改行x2 noteadd "<!DOCTYPE html>" noteadd "<html>" noteadd "<head>" noteadd "<title>helloHTML</title>" noteadd "</head>" noteadd "<body>" noteadd "Hello" noteadd "<img src=\"http://hsp.tv/images/bbs/mascot2s.jpg\">"//ネット上に公開されている画像 noteadd "<img src=\""+filename+"\">"//表示させたいローカルファイル noteadd "</body>" noteadd "</html>" exist filename filesize=strsize if filesize!-1 { sdim testIMG,filesize bload filename,testIMG,filesize,0 mes "LOAD IMG>>"+filesize+"byte" } sdim head notesel head noteadd "HTTP/1.1 200 OK" noteadd "Content-Type: image/jpeg" noteadd "Content-Lenth:"+filesize + "\n" headsize = strlen(head) sdim Response2,filesize+headsize Response2 += head ;Response2 += testIMG memcpy Response2, testIMG, filesize, headsize bufsize = varsize(Response2) mes"=============================" mes Response1 mes"=============================" mes Response2 mes"=============================" title "hspsock Server.as互換サーバー" port=999 mes "ポート "+port+" で接続を待っています..." tcpmake lis,port if stat : dialog "ソケットの作成に失敗しました。",1 : end onexit *bye *top repeat tcpwait lis if stat : break wait 10 loop tcpaccept soc,lis if stat : goto *top sdim s,1024 tcpinfo s,soc color 0,0,0 :mes "接続しました。("+s+")" sdim REQ_LINE,256 tcpgetl REQ_LINE,1024,soc color 0,0,255 :mes REQ_LINE sdim REQ,256 tcprecv REQ,0,256,soc wait 100 if instr(REQ_LINE,0,filename) = -1 { tcpput Response1,soc color 255,0,0 :mes "HTML REQUEST>>" }else{ //tcpput Response2,soc tcpsend Response2, 0, headsize + filesize, soc color 0,255,0 :mes "IMG REQUEST>>" } tcpshut soc ;// 通信終了を通知する repeat tcpfail soc if stat=2:break ;// 切断が完了するのを待つ wait 1 loop tcpclose soc ;// ソケットを閉じる goto *top *bye tcpclose lis end



chellcat

リンク

2021/11/3(Wed) 22:41:20|NO.94295

firefoxでは画像を自動で要求してくれてるみたいなのですが
microsoft edgeやchromeでは右クリックから画像を読み込むと表示できるものの
自動では読み込まないようです。
理由がわからないのですがほかのブラウザでも自動で読み込むようにできないでしょうか?



ベイン

リンク

2021/11/5(Fri) 21:17:24|NO.94305

> noteadd "Content-Lenth:"+filesize + "\n"

よくみたらContent-Lengthのスペルが違ってますね



chellcat

リンク

2021/11/11(Thu) 14:27:24|NO.94355

ベインさん度々ありがとうございます!スマホ以外の他のブラウザでも読み込まれるようになりました。



ONION software Copyright 1997-2023(c) All rights reserved.