6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ElectronでCORSで守られているレスポンスも見れるようにする

Posted at

CORSというウェブアプリのセキュリティのための仕組みがあり、例えばドメインが違うところに通信を行おうとすると、レスポンスが見られないようになったりします。
これは、ブラウザーがそのへんをきっちり制御していて、セキュリティを守るようになっているからです。

で、今回、私はElectronのアプリでCORSで守られたAPIを叩きたいと思ったのですが、Access-Control-Allow-Originにドメインが設定されていて、Electronからもレスポンスにアクセスできなかったのです。
Electronで実行されるとき、カレントドメインにはどうやらnullが設定されているようです。

本来の解決方法

調べた限り、こうするんじゃないかなー、という雰囲気を感じ取ったのですが、うまく動きませんでした。

webRequest.onHeadersReceivedでヘッダを書き換える

参考:https://imfly.gitbooks.io/electron-docs-gitbook/jp/api/session.html

要は、Access-Control-Allow-Origin: *が帰ってきたことにしてブラウザを騙してしまえばよいのです。
と思ったので、レスポンスヘッダを書き換える方法を試してみましたが、うまくいかず。
ハンドラが呼ばれていることも、cancel: trueが有効なことも確認できましたが、ヘッダーは書き換えられず。

const { session } = require("electron");
session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
  callback({
    cancel: false,
    responseHeaders: {
      ...details.responseHeaders,
      "Access-Control-Allow-Origin": ["*"],
    },
  });
});

今回やった解決方法

CORSというのはブラウザー上で動くウェブアプリでのみ有効な決まりごとです。
ブラウザー外で通信する場合にはこの制約は働きません。
そこで、実際の通信はElectronのNode.jsプロセス(メインプロセスと呼ばれます)で行い、その結果をWebアプリプロセス(レンダラプロセスと呼ばれます)に渡す、というだいぶめんどうな方法で解決することにしました。

main.js
const { ipcMain } = require("electron");
const request = require("request");

ipcMain.on("fetch", async (event, url, params) => {
  const body = await new Promise(ok => {
    request(url, params, (_, _, body) => ok(body));
  });
  event.sender.send("fetch", JSON.parse(body));
});
renderer.js
const { ipcRenderer } = require("electron");
async function fetch(url, params) {
  return new Promise(ok => {
    ipcRenderer.once("fetch", (_, body) => ok(body));
    ipcRenderer.send("fetch", url, params);
  });
}

ただ、この雑実装だと、通信が同時に走るだけで混線する可能性があるので、もうすこしいい感じに実装する必要があるでしょう。とりあえず、自分はこれで十分でした。

なんで、onHeadersReceivedが使えなかったのか、とか、一般的にElectronアプリでCORSのURL叩くときどうしてるんだろうとか、疑問はいろいろ残りました。

以上です。よろしくお願いいたします。

6
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?