やむをえない事情があり、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で。
<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