JavaScriptでリクエストするときCORSエラーが出てハマったので解決策をメモしておく。

ブツ

eyecatch.png

情報源

ハマったコード抜粋

const address = `MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu`
const url = `https://blockbook.electrum-mona.org/api/v2/address/${address}`
const data = {
    method: 'GET',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
}
const res = await fetch(url, data)
const json = await res.json()

実行すると以下のようなエラーが出た。

Access to fetch at 'https://blockbook.electrum-mona.org/api/v2/address/MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu' from origin 'https://localhost' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

キーワードからみるに、またCORSエラーらしい。ウザすぎる。content-typeがどうとか言ってる。これはHTTPヘッダでレスポンスのMIMEタイプを指定するプロパティ。上記コードでは'Content-Type': 'application/json',と指定しているが、not allowedだという。ならどうすりゃいいのさ? ググると以下発見。

どうやらContent-Typeの値を以下のうちのいずれかにしないとダメらしい。

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

よくわからない。このAPI、JSONを返すものでは? なのに、なぜapplication/jsonを禁ずるのか。たぶんセキュリティ的に何かあるのだろう。

まあいいや。とりあえずJSONもただのテキストだし、text/plainで取得したあとその文字列をJSON化すればイケるだろう。

解決コード

const address = `MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu`
const url = `https://blockbook.electrum-mona.org/api/v2/address/${address}`
const data = {
    method: 'GET',
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain', // ここを変えただけ!
    },
}
const res = await fetch(url, data)
const json = await res.json()
{
    "page": 1,
    "totalPages": 1,
    "itemsOnPage": 1000,
    "address": "MEHCqJbgiNERCH3bRAtNSSD9uxPViEX1nu",
    "balance": "1682705730",
    "totalReceived": "2866800590",
    "totalSent": "1184094860",
    "unconfirmedBalance": "0",
    "unconfirmedTxs": 0,
    "txs": 149,
    "txids": [
        "f405a0ca5009f405f11f69ead89bc34ec11a8bb40b70c623a06d473df27b2a76",
        "97709db041c0a6a0ad18b9118ac37b0cbc1b09df89ed074dac3e3c63a5d195f7",
        "1623d729a22e5a7308351aefd19a642265c056cc210de2eae9c0b979627e42ea",
        "fff7f83ac53af5cef66fd5d052ffd1731977001f1bc08687f073d2e1b959a9bc",
        "727b6c03bd71e0ee51c73cc236f7829a6591ed23ed0097e0a0ca385d82a30714",
        "65d07b7fbae12d5714fda8d275c3141eb68a94ab674ee35f08a08ae997933890",
        "a833ab133d09aa3abb9160f0d9f7e38ebf9205224e12f14b4751e2e3849920cb",
        "bd94a6f31e0eb976ffa17bafbf34fbc08520cac93c0769f7f194d4c8949567ab",
        "f1c3774f28c5a9e5fca5066f8634af23395e620ed2239aa26e79cef1145978d3",
        "cb0b1a48c08f1c4177fae43f66b986c3c5f8c40648e13901d6a2247c9e1abccd",
        "9bd393475f9232ed6872099817c71787637fffe28236ec57c467f66b02a8f699",
        "394eabd9532a09793adf03f229effc88c55185dba59b6fce53559013ba377146",
        "f5421dfef52c33822038c6ecaba1cb146943c67aa99bfb269f2be7566952decf",
        "bd4e1f0a6373027d38e7a284969df79f4ffa78f3973b282546097c3be8f33f75",
        "e3f5b65087c770e7a218ff775cd1c33ae5393aa8159465b33cd6bb2e301e91fe",
        "570d83eceb834dda1e601e1a0349602310a07c48d14e6f88375e7c7eacc88438",
        "cab09e03c9f58be0e89f71a62c9fbc3fe26f16005be66c95e428dbd1d5900548",
        "83cdacb3932e4fa28909c838c37d95a053e049f2532f4b58cf609ee61363ba0f",
        "ae30aba3825721ac1ca61678c52b257427ef71557209357a58ce4c5a5c2f0dd9",
        "1d91bbcb5f20b457313e738224012b1e1b44eb275839c2867dc997b9b7c04e0f",
        "16cd6acae8f8d831808f0fbc84bbcb5b61b70fe18326424450d7143e592da3c7",
        "85e702bde5f359772a97784628119170d5823a79adf1d7e0f2c51378e35cd081",
        "a448c5b0cfc49db119519fadba4f99d235d16b46bff6cfb4de1d89ff2180fc3b",
        "a932f303af8829932f69fd8708a046a638c0132a885536a0109d4085fe5561eb",
        "465fd6191ebe50495c55fc922ac9e70c61f1dafc18f0852f52f874d7ca8d7273",
        "6541964282c63b17c7cb9a1efa371576d2c3d4ea77ebc447dcce5eb76cfd0d58",
        "fe6513275f3607f809f386a0c4be924e287f456b0251e471ad6d446cbf20a685",
        "2313631a3afcafbaead1e1a11d09c09f3081c5697856f1ef4f738b92e574ad09",
        "76933f139080ff35a7c2daa0ee7bd9ecf812063290b4475a6f1a3ae7764ce1f0",
        "3e911a24be7101a4a03bd1bbdb17ef160fd77f9ab766c1cb631367829e1a57f4",
        "e4a0a483bedefc033ff2f5991520b411e4b01d5ae719d5a6a9bce252dfbfcdc3",
        "b18a0aef0726eb1e83d4753b37420af5402a1110f3a2c009d656a618fe47e9c8",
        "dfd1a387ec540d6da946fb544824597a542d7e1c5b4079bd8805d26bde536159",
        "327c74ee1853668a558036c3ca816a5ab01e7f297fbad95f26635e0867959415",
        "289fe75242d284af6905a16c23797ddd0b93df974ad5429ea96bc325b7dcd853",
        "aa8ebd4b2c543d04e744aed238ac532479d75bb24138d6c72c8b0dc375ebcf61",
        "42da297750dbf5a6dd3181780d7bfcb1dc646e22063f4e7d9b0c9133ff25b98d",
        "6ec59ba9196a32ba3f340e894eee3a5d97c1ab006947b0a31364101606ed3e5c",
        "364b1eb98fd98c65ce6957f1cb61c10ef16de0fa7ea197decf8fce83f78ec5bd",
        "7b423d28e2328d96768f5ecbb7e83ee29c2ef2d418913bc96084f60a8312eeb9",
        "608d51fcb92f35853aaa94ea69acf4b134ce4d8008ddb20a935e55049eae349c",
        "268b109cf0269f1d93d880c3b08cc3da074537ebacb12528bbb542c83447e5fc",
        "1b6ee3272b2c16572da7370ed65d1b2d5e253ab552fa411a24956b8610421897",
        "883c333dbf94ab25602e82112c5008eb81bb129b3f8cf9ddfe63d840aaaf381d",
        "5e708bc9c5cec0812d66808ff07a4af664c02a8aaf970cbd0092f23a410e1dc0",
        "5244c2179e164a96e5e3feb9d165aef6090f0281658105ea6e34f54e59503d41",
        "bbae4abe7b090030fb37f82141669bbc3eada55bd7ea716d5d44d02a07253091",
        "5894d2facf6e6083141aca34a9ba81ceb5e116174233d328576e1e686678a292",
        "92ba464b926cda317908d51c8702d8494d838fe80d3a5892c473dddbc029dd0e",
        "7271195349926a04f667f8dd3751f24559cf9da321c74d41d498c4999b749960",
        "f8bc7cf3b5776624493251ed0f5a5c286303d68dbc22fccec0f61106a90f82a0",
        "9722cde73f91bf04874fedde8c1989388dfc83d5618a7f8a5f02728ac1a8e2d6",
        "0d125e81934cb58c38d00c6c0ecccf1469288242bcf6e4fe16da955ad7364510",
        "f9a387695fee01cb0c2e0c17629c261ca01160fb88f8ebe9f22453e3131cdab9",
        "904325eadce09b36d629518580c4270fdbb4f468b6e27c5f8b84798b787ef023",
        "7a3ec354f66dde32719131a099df46a67024eeea336e163bcd224414684f64ee",
        "b5d71f29223c92027db483ecf34c1f23bf173e242e12a6fbfc161a78f2fefd5c",
        "ff9fe93e566312b5451876446cfe22e73e97bb33a4db554d63a6a45eb457586d",
        "18612323ca3f8a4cb953c9c2b406ae8cd86a40dbe3a98bfe9c5bc922f01655f0",
        "32e5bd7baf9f5f74aef8ab38cc09b6cd5339fbc1a9727b7a77e29f3c7c2c5280",
        "c00473a5a819b922469a9369fd204f2e94e327fded709e9ea6c3181f7f1b3007",
        "fc5f9aef3d5e510784285b029061e60962feb69327e643759d3f895c2ea61b96",
        "28104be0b1ee0a6dddb61d800366759515f45225e5670b78b8909e3e1e83d067",
        "e9531cd7cb4b63020459a7f6a51be3d1cfd5972d267c8e9fb405574d19597a73",
        "7522827e1caa01f4e9ed2cef80183b3d55f47e2dd338e3fda07fd13c7f6e3867",
        "eca4d29b8eeb07b2838d39b85f595bb3b68876e214927fac351a5e211f5a16c8",
        "95d2a759421f0c68a7729abab36005e756ec815cc4146e2ae1af927cf2846909",
        "d368d3fe4f54abaacebe0e69473138317950b592bc018a6155978add98ded9b3",
        "28483ebbd0b142a5fff43e7ce94b4a43b03cda9d7c462dc5be487eae52e634ea",
        "39f78e1c8da9cabe1461d24c8d75b792f7a2ffbb4dbb5dfc05c7d06a5d913760",
        "d62291fd82352364aedc7778df01156b187da637b1c6f18978083293ae45ee55",
        "9cc11243498f18d4a65f8d58f54d122d481e6ae2f504210ebcb6ce7ce5a37115",
        "9c302ffe3a397052dcce7627b9796e775254398197c68c6503953e2cf98a2485",
        "e19f422375439496abd26da6c9c5f251fa604afee4f54cb874d1a0309436cdb1",
        "9a5bee5638e7892cde8ae9b8e921f74cc09fa01615a978832922db98fd314248",
        "6d4e016c8c958804779d6ead471c298eef868ad7525838885ca5f2fe0e168bef",
        "53aa1e1df28be33beae69e655f4eaebe6dca3ccfc8a7d522ecacc399e422d843",
        "b999d888560d0e1a17d1f0e30bd438135a8d9e90d6793f94bc8c650a46c6a707",
        "1c067d029776d0d97b6fa7ffb2bb7cbc375bec428db0b748be2101d33525eedd",
        "3c5f60c410d931a38a417fb08e07c554482bf6509ccdca5edc04a39ebbe9bf9f",
        "b9e124a3f032d5007472ca1f553c093efa00a391243b1aac0d21f2becdada7d8",
        "0b8688a630eff478459bab9e420045589936631dba21f89576b36d3ebdde7b76",
        "4a53154c08e2916076c6ad495494b7bc155e8f4481fe554f8defea3599f9a0e0",
        "e2803d73c4e6ca70e4e93b26692bf39c902b144a339f22bcc58003dd2c6102dd",
        "f1419fa4f51d3e48f564121a80966fa82dd0c5e2ec3e79a866d4fe42d63d0083",
        "fb0050ac32ef1dcb926cf35eedd7243904a543394be0b66cb6c122f86e89198e",
        "986fac8358c68bf4e44010bd69e7f37841347061f049f716e675895ec3bafe27",
        "538a3d92a5fe0467bd78bb85de002f132ff151b63015e9720eb190aec7f3c8d5",
        "b0a35bf1be5892e435610eabbfcdaa9f06e8442d935d8f8ca425c9199eb8db0f",
        "ac80e9582e257dc77bbbc84beb8972bba3201b2f77f2d5e02f883c6da66e7544",
        "f6f8bcc2af150146b066ff64725fca4df82d6712ac19f9ab12bb12cf21dfb6ad",
        "cb64e1375e87b3be44e14ef6c5fff92915495fd7064f6b23a71d7214c7b0e95c",
        "19ee2ef83acc12ce84a2f60325718dc9a4b70b9d83d46d9f5fc71d7cd07c8279",
        "a13f34982c4bf9886764c80e08558f95f724d5daa6931185450c16492c0c5085",
        "b16db781bd3c4ebd17d815bb5117fd5542fa560a4c4c4a3107b2c3a343524e43",
        "00573fae17c9957730a9e3250b8ab20d19ed88fd1b46c3d092e298192766e5d0",
        "46315b8e698c326fc8167b0466d11aa0046d89d9c79360564d504b85c2b4e0ba",
        "f74731a9e91118d1274a20b85b317cd0bed34686408bdba95656bd4be918d644",
        "0cd08224a54f448f4c7fb856374c4e98eb2eb48718261854343a02ab6f1e5b21",
        "75cd31f88453a5277962e7dffb7853e599e9be909a64252e4bcf1c773bfbee49",
        "99f79eecbbd28ef43175dec6809d0f8abd9e49b56ab45d8b1a76e252f7ecd286",
        "8e7e64a54402876d7d87916a5666efa3cc2b1bd67b7b348c4a65b046d388e49b",
        "adec2d9816f01b4890a6614158b0f6fee311cfcc5d64dd9abc91e05c320dba74",
        "cb49c13ddc650808187d4cb0d1f19ef7dbefe88fb7be124f57c7a1074b71cc6d",
        "89e3f644050f90bc4a72ac357c070166d1189faa64be1cd0976dbb16fa87c7f9",
        "1d2ba7cddbbf51ded3701ebd74425fdc2c832880601f17c76bde3ac7e7390cb2",
        "3fc205e53cedeeb828d491ec8a7bbaaeb38cc8c0f0135523953f41c594626dae",
        "206ad6442b309f37e9d0af8219d36207ce51b03d36b4b624a884f2c503180d9a",
        "559cc4fe70bea88c4f702ae1e86a70c641353c4ae63a961f982865212454c04b",
        "44df3397289311479bef3853e0efe14e059ead9ce4488b38f3fd99fb9a78f9c8",
        "7774cc9cc79ac314231061e8cd3743d35417149a9167e81349356ed953eab86d",
        "762b2d11c66649374fa02f813a134f0e41c5b87d05192bc3c5f99b313bbff64d",
        "c044b53c833a6d470268cd9f76d15a35e28e80310b704cf3dbb19fa69cab13d5",
        "de1da180409b74ed103fe4bb61c57b6bda3aad036751ec88dd9c5a78c813e888",
        "b0dddd6202363324474d3f6e2580fceaacd66ce7e123e92cf28a849e315d1664",
        "efe6b3efd5c22069109ed6b22468713082f8dcef137f16daafe63c9bfd9e78c9",
        "0e6f6844385dd07856194b66aca40a94d40a7d109952b07bcff9782971c234c9",
        "be13adb03b5b7f1b24e0bf18db01d5092406dcd3617b96e84cb1375e540c1bf5",
        "e55d76e30e2b59d589cbf056baa0d6be4ce900bb6a7b59426f39eff715689665",
        "c0ea3a09660da2f270f5ecca695caa0ff4047f9c2a7dec2d5222eb10c56337e9",
        "131f491bebef29fa4a9545ea894552bb302065dfadc405752c6f31142e5cad02",
        "4e490864c0b975cc9c504adcec03bd1ecb793c3b0559b5ae1fc37e7af014b17a",
        "91c8765e1b745420d288f9064b659aaadcb08d0ec9f0d05fab195f71e23b41cc",
        "c15d93a315941c21a81d50a8fedbbf1fb0aae50217b1659b31039af3d6ae1f31",
        "f78a61b91269bd8b16993f6f3d49c5ae23ed11b2376b3b394ae6a525308798bb",
        "0524ae5c8415e4893c57604e5950c88553da673bcb6d8fd9dea2a5fd0eb7041b",
        "a5e3905b4181a0e52e6e39165288f248b3c758604ed5ea99c9d96d98f005fde1",
        "bcad39c53288d19870b6ecb156cb89786c9576a1786b1d0d7e26338c56f81635",
        "87236c5ba27d094ada5b110fdbd8513cf266cb4d442d7bb55bb7845a8e06388c",
        "f30f6aa525b5e8e49d1cf06a30b1696c1ed7aa60e35f9ed60840db3e64f78a5f",
        "4de2f455ec1c40f0962abf3d35cf8902d82f5a0e94170b882127578cda3bd26b",
        "43e2a380e0f1a66f7dce9d3c62ca004bbe312b2e05f5b8f832f3c43598dd4d55",
        "b01061fec4cf170c9556d1ff4ba2c9a78db3a0230acaf73bfbc7649ad21fca93",
        "f8c62ce8de3ec286d988499621f78d0aa4191d50e84eea7bdc7e4f3d4c365923",
        "8f50c7f4c35fbd77a0ae669baf5f1d4fa69d04e34b3f777630d69156938c7f2c",
        "4b0a9eeda48a03c3c09caee4f3608784669f87d9d475aaecc8c0a9d98da48c66",
        "38646d6828db903a169117e5db8cdadb049fd65f2515c81900a9c3fccdc469b2",
        "831c41287d17e58b7d566d875c203751e89c2c272cdfe8ad884ca848811c412c",
        "9004fe5012c3bc067b48147dc5e03ece0bd1c92032be3b42823597ecb090dc63",
        "4c2d542a8a09556ee75a543aa353eb725ea6d3c5f8668683463ace8f7fcf9937",
        "35c204ccb2709bc0eb15a736991f020d45c8f20222ce5462207deb7b268cf752",
        "f48ba7e92f964a0f25bc2cbd0d025be5ecf6c4ed27ead3ffb453c3b0451fa2f3",
        "bbb38720563500d49f9ab60f05c941c0b24fdc6294a63ca667ba45a03be6a2af",
        "2cd0188f73a4d469deb86ed6f7c3f21a28b4e30662fd36432401f0045d023e9b",
        "864241ffea4bbf87246101e0489b82d6da9899da94bed9f9f3254c9af376c1fe",
        "7ad15ec4dc2fe3d50907f9f65258a1d16780d5550daf3819e24901d185e23be8",
        "f361755e992a137104045aab29a3c8aa5a5b1728f3da1f0c14d6bc535d67aa5e",
        "bdb94566166bab6e019df2ea8497db71b7bd9d69f05dd1bea299600f4929941b",
        "483aa8414711bb71246f355240cb4a79a5292d8b7b152caca8c985b0c6e6acd0"
    ]
}

取引データを取得できた! 執筆時点でtxidsは149件あった。

"itemsOnPage": 1000,は一回のリクエストで取得できる上限値だと思われる。それ以上を取得するにはページネーション処理が必要っぽい。

あと、ソートは新しい順らしい。search_raw_transactionsのときは古い順だったのに逆だね。

展望

妙なハマりポイントがあったが何とか成功。たぶん他のAPIも同じようにイケるはず。

あとはこうして入手したデータをローカルに保存できれば、技術的な課題はクリアできそう。

そしたらトランザクション情報から支払か受取かを判別する方法がわからないせいで生じた取引集計とユーザ相関図のバグを治せるはず。

やっと光明が見えてきた。