はじめに
nem2-sdk-typescript-javascriptのListenerを使った際、以下のようなエラーに遭遇することはないでしょうか。
Access to fetch at 'http://13.114.200.132:3000/ws' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
自分の経験では、クライアントサイド(ブラウザ)でListenerを使おうとすると出現します。
エラー的に、CORSを設定しなければならないように見えますが、そうではありません。
クライアントサイドでListenerを使う場合は、サーバーサイド(Node.js)の時とは異なり、WebSocketオブジェクトをインジェクトする必要があります。
例えば
例えば、Nuxt.jsで以下のようなコンポーネントを作って利用したとします。
<template>
<div style="margin-top: 2rem;">
<button @click="listenConfirmed" class="button--grey">confirmed</button>
<pre style="text-align: left; font-size: xx-small;">{{ JSON.stringify(confirmed) }}</pre>
</div>
</template>
<script>
import { Address, Listener } from 'nem2-sdk'
export default {
name: 'Account',
data() {
return {
confirmed: []
}
},
methods: {
listenConfirmed() {
const listener = new Listener('http://13.114.200.132:3000');
const address = Address.createFromRawAddress('SCA7ZS-2B7DEE-BGU3TH-SILYHC-RUR32Y-YE55ZB-LYA2');
listener.open().then(() => {
listener.confirmed(address).subscribe((x) => {
this.confirmed.push(x)
})
});
}
}
}
</script>
<style>
</style>
開発者ツールのコンソールに以下のようなエラーが表示されると思います。
解決方法
Listenerの第1引数にはws
から始まるURLを、第2引数にはWebSocket
オブジェクトを渡します。
なので、以下のように書き換えます。
listenConfirmed() {
const endpoint = 'http://13.114.200.132:3000';
const wsEndpoint = endpoint.replace('http', 'ws');
const listener = new Listener(wsEndpoint, WebSocket);
const address = Address.createFromRawAddress('SCA7ZS-2B7DEE-BGU3TH-SILYHC-RUR32Y-YE55ZB-LYA2');
listener.open().then(() => {
listener.confirmed(address).subscribe((x) => {
this.confirmed.push(x)
})
});
}
何かトランザクションを送ってみると、ちゃんと取得できました。