質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.78%

HTTPのステータスコードが200だけどCORSのエラーが出る理由

解決済

回答 5

投稿

  • 評価
  • クリップ 2
  • VIEW 1,018

nozomiiii

score 5

前提・実現したいこと

問い合わせフォームに入力されたデータを非同期でGoogle スプレッドシートに送りたいと考えています。
そこでJavascriptのfetchを使い、POSTでデータを送信しGASが実行されスプレッドシートに書き込む処理を
作成しました

しかし処理自体は書き込みに成功し、HTTPのステータスコードも200が返ってきているのに
fetchの処理でCORSのエラーが発生しており、エラーハンドリングされます。

そこでCORSのエラーを解消し、正常処理のステップに進むにはどうすればいいのか
また、ステータスコードが200でもエラーになるのはよくあることなのですか
教えていただきたいです。

発生している問題・エラーメッセージ

Access to fetch at 'GASで作成したAPIのURL' from origin 'null' 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.

該当のソースコード

ajaxButton.addEventListener('click', function () {
let name = document.forms.google_form.name.value;
let hurigana = document.forms.google_form.hurigana.value;
let email = document.forms.google_form.email.value;
let msg = document.forms.google_form.msg.value;
const params = new URLSearchParams();
params.set('name', name);
params.set('hurigana', hurigana);
params.set('email', email);
params.set('msg', msg);

const url = "GASで作成したAPIのURL";

const headers = new Headers({
  'Content-Type': 'application/x-www-form-urlencoded',
})

const data = {
  method: 'POST',
  headers: headers,
  body: params,
  mode: "cors"
}

debugger;

 fetch(url, data)
 .then(function (response) {
   if(response.ok) {
      console.log('正常終了しました');
    }
 })
 .catch(function (error) {
   console.log(error.message);
   console.log(error.stack);
 })
});
function doPost(e) {
  var ss = SpreadsheetApp.openById('シートが存在するURL');
  var sheet = ss.getSheetByName("シート1");

  var name = e.parameter.name;
  var hurigana = e.parameter.hurigana;
  var email = e.parameter.email;
  var msg = e.parameter.msg;

  // データ入力
  sheet.appendRow([name, hurigana, email, msg]);

試したこと

modeをno-cors指定にすると処理は正常に終了するけど空のレスポンスが返ってきて
.thenの処理で中身を確認することができなかった。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+5

「CORS」や「Access-Control-Allow-Origin」を調べてください、で終わる話ではありますが、エラーの原因と対処方法を簡単に書いておきます。

エラーの原因は、API のレスポンスヘッダーに Access-Control-Allow-Origin がないためです。
JavaScript ではセキュリティ上の理由で、アクセス許可がないレスポンスは取得できないようになっています。
ちなみに、HTML と API が同一オリジンであればこのヘッダーは不要なので、その場合はあまり気にする必要のない話です。

JavaScript側だけでは対処不可能であり、API側でレスポンスに Access-Control-Allow-Origin のヘッダーを適切に指定するか、HTML と API を同一オリジンに移動させるかが必要です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/20 17:45

    ありがとうございます。
    レスポンスにAccess-Control-Allow-Originのヘッダーを適切に指定できる方法を探してみます。

    キャンセル

checkベストアンサー

+2

HTTPのステータスコードが200だけどCORSのエラーが出る理由

HTTPのステータスコードはWebサーバーが返します。
CORSのエラーかどうかはWebブラウザが判定します。

よって、Webサーバーの処理が正常に終了しレスポンスを返す場合はHTTP ステータスコードは200となります。このレスポンスをブラウザが受けて、ブラウザがCORSのエラーにするかどうか決めます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/20 17:42

    ありがとうございます。
    webサーバもwebブラウザの違いがあったのですね!
    勉強になりました。

    キャンセル

0

Fetch APIでデータを得るアプローチが間違いなので、GASのAPIを調べてください。

var ss = SpreadsheetApp.openById('シートが存在するURL');

openById() の第一引数に指定できるのはIDですが、必要としているのは、URLなのでは?

Re: nozomiiii さん

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/21 08:16

    ありがとうございます。
    スプレッドシートに書き込むことは成功しているのでシートの取得はできているのかなと思っています。
    一度URLに変えて試してみます。

    キャンセル

0

GASの処理は正常に終了した場合レスポンスにAccess-Control-Allow-Origin: *を自動で付与してくれるみたいです。
異常の場合、Access-Control-Allow-Origin: * がヘッダーに付与されず、CORSのエラーが出ます。
今回の場合、処理が異常と判定されていたのはデータの送信部分と思われます。

const params = new URLSearchParams();
params.set('name', name);
params.set('hurigana', hurigana);
params.set('email', email);
params.set('msg', msg);


としていた部分を

let form_data = new FormData(document.getElementById("formのID名"));
form_data.append('name', name);
form_data.append('hurigana', hurigana);
form_data.append('email', email);
form_data.append('msg', msg);

に変更

  'Content-Type': 'application/x-www-form-urlencoded',
})

としていた部分を削除しました。

こうすることでdoPostの処理が正常に終了して、エラーハンドリングされなくなりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

Stackoverflowでこのようなスレッド1スレッド2を見つけました。質問者様のGoogle Apps Scriptのスクリプトが途中で切れているため、これが直接の原因かどうかわかりませんが、もしもdoPost()が何も返していないようであれば、doPost()の最後に次のスクリプトを入れてみるのはいかがでしょうか。

return ContentService.createTextOutput("ok");
  • スクリプトを修正した際は、Web Appsを新しいバージョンで再デプロイしてから動作確認してください。これにより最新のスクリプトがWeb Appsへ反映されます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/11/26 19:49

    処理が正常に終了していなかったことが原因みたいでした。
    一度上記のようなコードを追加した際もCORSのエラーがでたことは確認しています。

    キャンセル

  • 2019/11/30 10:51

    既に試していたとのことで、気付かず申し訳ありません。お役に立てず申し訳ありませんでした。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る