GASのおかげでwebエンジニアに近づいた
はじめに
こんにちは。スペースマーケットでWebエンジニアしてます、新卒のdumbled0reです。
今回は初めてGASに触った時に発生したエラーのおかげでWebエンジニアに近づいたお話しです。
こんなエラーが発生した
Access to fetch at 'https://script.google.com/macros/s/[デプロイURL]/exec' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
JavaScriptのコード
fetch("https://script.google.com/macros/s/[デプロイURL]/exec", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "佐藤太郎"
}),
})
Access to fetch at 'https://script.google.com/macros/s/[デプロイURL]/exec' from origin 'null' has been blocked by CORS policy
オリジン 'null' からの 'https://script.google.com/macros/s/[デプロイURL]/exec' へのアクセスは、CORSポリシーによってブロックされましたと言われたけど、オリジンとかCORSポリシーってなんやねん、、
※ローカルファイルをブラウザに表示しただけなので、オリジンがnull
になっています。
オリジンとは
オリジンとは 「プロトコル」「ドメイン」「ポート番号」 の3つの組み合わせで決まります。
例えばhttp://example.com/app/index.html
のようなURLが存在した場合、プロトコルはhttp
、ドメインはexample.com
、ポートはhttpのデフォルト値である80
(デフォルトの場合は省略可能)なので、オリジンはhttp://example.com
になります。
今回の場合、ブラウザ側はオリジンがnull
でGAS側はオリジンがhttps://script.google.com
になるので、異なるオリジンになるということか。
CORSとは
CORSとは「Cross-Origin Resource Sharing」の略で、ブラウザが異なるオリジンに対してリクエストを送る際のセキュリティチェックを行い、リクエストが許可されているか確認する仕組みのことです。ブラウザは他のオリジンからのデータ取得を制限しています。
つまり、GAS側でnull
というオリジンを許可すればアクセスできるようになるということか。
GAS側でAccess-Control-Allow-Origin
を*
にしてもなかなかエラーが解消されない。
どうやらリクエストには2種類存在するらしい
リクエストには安全なリクエスト(Simple Request)と安全ではないリクエスト(Non-Simple Request)が存在します。
安全なリクエスト
- HTTPメソッドが以下のいずれか
- GET
- POST
- HEAD
- ヘッダーが以下のいずれか
- Accept
- Accept-Language
- Content-Language
- Content-Type(以下のいずれかの値のみ)
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
安全ではないリクエスト
上記の安全なリクエスト以外になります。
例えばHTTPメソッドがPUT
やDELETE
やOPTIONS
、Content-Type
の値がapplication/json
などです。
そして、この安全ではないリクエスト時には「プリフライトリクエスト」というものが走ります。
プリフライトリクエストは実際のリクエストの前にブラウザがサーバーに対して「このリクエストを送っても大丈夫?」と事前確認しています。
今回のJSのコードでもContent-Type
をapplication/json
に設定していたので、プリフライトリクエストが走っています。GASはOPTIONS
を受付られない仕様になってるそうなので、本来ならAccess-Control-Allow-Origin
を適切に設定すればOKのはずですが、 OPTIONS
で飛ぶプリフライトを受け付けないから今回は別の方式を取りました。
対処方法
プリフライトが走るとCORSエラーが発生するのが分かったので、プリフライトが走らない安全なリクエストに変更したらよい。2つ紹介します。
Content-Typeを変更する
Content-Type
をapplication/json
からapplication/x-www-form-urlencoded
に変更して、Content-Type
の値にあった送信をするように修正しました。今回はapplication/x-www-form-urlencoded
にしてますが、text/plain
でも大丈夫です。
JavaScriptのコード
fetch("https://script.google.com/macros/s/[デプロイURL]/exec", {
method: "POST",
headers: {
Accept: "application/json",
// application/json -> application/x-www-form-urlencodedに修正
"Content-Type": "application/x-www-form-urlencoded",
},
// URLエンコード
body: new URLSearchParams({
name: "佐藤太郎",
}),
})
GAS側
function doPost(e) {
const name = e.parameter.name;
}
GETメソッドをPOSTメソッド風に扱う
GETメソッドをPOSTメソッド風に扱うなんて普段の開発ではしないことですが、doGet
関数を使う予定がないのであれば、手っ取り早いです。
JavaScriptのコード
fetch(`https://script.google.com/macros/s/[デプロイURL]/exec?name=${encodeURIComponent("佐藤太郎")}`, {
method: "GET",
headers: {
Accept: "application/json",
},
})
GAS側
function doGet(e) {
const name = e.parameter.name;
}
これで無事にJSとGASで連携することが出来ました!!!
まとめ
はじめてGASに触ってみて、Webエンジニアであれば当たり前のように知っていることも少しは分かるようになり、Webエンジニアに近づけたのかと思いました!GASに感謝!!!
さいごに
スペースマーケットでは一緒にサービスを成長させていく仲間を探しています!
新卒でもフロントエンドからインフラまで幅広く関わることでき、成長できる環境があります。
ご興味ある方はこちらからご応募お待ちしております!

スペースを簡単に貸し借りできるサービス「スペースマーケット」のエンジニアによる公式ブログです。 弊社採用技術スタックはこちら -> whatweuse.dev/company/spacemarket
Discussion