やむをえない事情があり、JWT認証を通過して画像を表示させる必要があったので、
XHR(Ajax)で画像を読み込む方法を調べました。
同一ドメインならこんな苦労はしないのにーとか最近そんなことを悩んでいます。
サーバーサイドのコード
何でもいいのですが、最近お気に入りのexpress
サクッとなんか書くのが楽なんです。環境構築も長楽だし。
JavaScriptいいお。
Nodeはversion 12くらい。Expressはversion 4です。
$ express --view=ejs myapp
とかでサクッとひな形作って、
とりあえずroutes/image.jsとかいうルーターを作り、単にバイナリデータを返します。
const express = require('express'); const router = express.Router(); const fs = require('fs'); router.get('/', async (req, res, next) => { fs.readFile('./public/images/nyam.jpg', (err, data) => { if (err) { console.error(err); res.sendStatus(500); return; } res.writeHead(200, {'Content-Type': 'image/jpg'}); res.end(data); }); }); module.exports = router;
index.jsのコードは省きます。
nyam.jpgというのは猫の画像です。にゃーむ。
当然PythonのFlaskでもRuby On Railsでもなんでもええです。楽なやつにしましょう。
Spring Bootでもいいですが若干だるいと思います。
フロントエンドのコード
jQueryでも実はできるとのことですが、まぁXHRでいいでしょう。
Blobってのを使うと超絶らくちんです。
Base64ならなんでもできるぜい、っていう素敵なおっさんから話は聞いてましたけど
めんどっちいんでBlobで。
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <div style='height: 300px;'> <img id='img' alt='nyam' height="300" /> </div> </body> <script> var loadBinaryImage = function(url, cb) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { cb(this.response); } } xhr.open('GET', url); xhr.responseType = 'blob'; xhr.send(); } document.addEventListener('DOMContentLoaded', function () { loadBinaryImage('./image', function (blob) { var img = document.getElementById('img'); img.src = URL.createObjectURL(blob); }); }); </script> </html>
これを調べた動機
そもそも画像を表示するなら
<img src='http://localhost:3000/images/nyam.jpg' alt='nyam.jpg'>
で事足りるわけですが、
やんごとなき事情によりAuthorization: Bearer [token]
がないと画像が取れねーよって状況になってるので調べました。
さてと動画というと…
206の応答を返してごにょごにょして…
こんな感じでできるっぽい。
重い動画の場合は知らん。
そもそもほかのドメインに動画読み取らせるのはなぁという…。
参考リンク
XMLHttpRequestで取得した画像バイナリをJavaScriptでロードする - kinjouj.github.io
AjaxでバイナリのJPEG画像データを受け取って表示する - Qiita