three.jsをいじっていたら
three.js の TextureLoader にある load ( url, onLoad, onProgress, onError )
に外部URLを直接入れてもCORSに関するエラーが出てきてしまいました。
var url = 'https://example.com/image.png';
(new TextureLoader()).load(url, (texture) => {
// texture は three.js の Texture
// https://threejs.org/docs/#api/textures/Texture
});
サーバ側から叩けば問題ない
CORSについて理解ができていなかった私は (今もまだわかっていない) サーバ側からリクエストすれば回避できるということを知りませんでした。
というわけで express を使ってサーバを立ててしまいましょう。
TextureLoader.load
の url
や <img>
タグの src
にはbase64を指定できるので、今回はbase64を使っています。
ディレクトリツリー
main
├── server
│ └── index.js
└── src
└── index.html
server/index.js
const express = require('express')
let defaultPort = 8000
let app = express()
let server = app.listen(process.env.PORT || defaultPort, () => {
console.log('start server listening', process.env.PORT || defaultPort)
console.log('http://localhost:' + (process.env.PORT || defaultPort))
})
app.use(express.static(__dirname + './../src'))
// GETリクエストで画像の外部URLを受取り、base64を返す
app.get('/url2base64', function(req, res) {
const url = decodeURIComponent(req.query.url);
request.get(url, function(error, response, body) {
if (!error && response.statusCode == 200) {
data = "data:" + response.headers["content-type"] + ";base64," + new Buffer(body).toString('base64');
res.send(data);
} else {
// 画像がなかったら透過gifを返しておく
res.send("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEHAAEALAAAAAABAAEAAAICTAEAOw==");
}
});
});
src/index.html
<img src="" alt="">
<script>
var url = "https://www.google.co.jp/images/nav_logo242.png";
var xhr = new XMLHttpRequest();
xhr.open('GET', './url2base64?url=' + encodeURIComponent(url));
xhr.addEventListener("load", function(e) {
document.getElementsByTagName('img')[0].src = xhr.responseText;
});
xhr.send(null);
</script>
あとは main
ディレクトリ配下で
npm install express
node server
とすれば http://localhost:8000/index.html にて、指定したURLの画像が表示されるはずです。
デベロッパーツールで <img>
タグの src
を見てみるとbase64で指定されていることがわかると思います。