LoginSignup
17
14

More than 5 years have passed since last update.

Go言語(Go-Json-Rest)のCORSでのハマり。Safariだけでハマった話。

Posted at

go-json-restを使ってAPIサーバーを立ててCORS対応する話を前に書いたのですが、Safariだけ挙動でハマった話です。

参考: Go言語(Go-Json-Rest)でAPIサーバーを立てるときのCORS設定 (Basic認証機能付きも)

ハマり内容

前のコードと同じ内容です。
ChromeやFirefoxの場合はこれで問題無く動作していました。

  • Go側
app.go

/*省略*/
  api.Use(&rest.CorsMiddleware{
        RejectNonCorsRequests: false,
        OriginValidator: func(origin string, request *rest.Request) bool {
            return origin == "http://localhost:3000" || origin == "http://192.168.43.158:3000" || origin == "http://localhost"
        },
        AllowedMethods: []string{"GET", "POST", "OPTIONS"},
        AllowedHeaders: []string{"Accept","Authorization","content-type"},
        AccessControlAllowCredentials: true,
        AccessControlMaxAge:           3600,
    })

/*省略*/

  • フロント側
api.js

$(function(){
  var host = 'localhost:8080';
  var rand_param = '?ie=' + parseInt((new Date())/1000, 10);
  var endpoint = '/countries';
  var url = 'http://'+host+endpoint+rand_param;

  function make_base_auth(user, password) {
    var tok = user + ':' + password;
    var hash = btoa(tok);
    return "Basic " + hash;
  }

  $.ajax({
      url: url,
      beforeSend: function (xhr){
        xhr.setRequestHeader('Authorization', make_base_auth('userud', 'password'));
      },
  }).done(function(data){
      console.log(data);
  }).fail(function(data){
      console.log(data);
  });

});

ここまでは前回と同様のソースコードです。

chromeやfirefoxだと普通です。

safariだけでエラーが発生。(しかもPOSTのみ)

※ safariのバージョンは8.0.7(OSはYosemite)です。

iPhoneで確認して、最初はiPhoneだけの問題かと思いきや、Safari特有の問題みたいです。

※ GETメソッドは問題無く動作してました。

解決: Access-Control-Allow-Headersにoriginを追加しましょう。

色々試行錯誤した結果解決しました。

Access-Control-Allow-Headersにoriginを追加することで解決しました。逆に言えば、Safari以外はこの指定が無くても動いてくれるんですね。

go-json-restの実装の場合はAllowedHeadersoriginを追加します。これでsafariでも大丈夫です。

app.go

/*省略*/
AllowedHeaders: []string{"origin", "Accept","Authorization","content-type"},    
/*省略*/

これだけで半日くらいハマった...
Safariだけで発生した問題だったのでブラウザごとのxhr実装とかの関係かと思ってフロント側調査ばかりしてました。

こちらの記事(GolangでXMLHttpRequestLevel2+CORSのプリフライトが通るサーバーを立てる(BasicAuth付き))をもとにサーバーを構築しなおしてみたら同じJSコードで通ったのでGo側の実装に問題がありそうだという糸口です。

まとめ

GETメソッドは問題無く動作していたのでややこしかったです。
Access-Control-Allow-Headersはしっかり設定しましょう。

勉強になりました。→ 異なるドメインのURLからデータを参照する方法 - Cross-Origin Resource Sharing

17
14
1

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
17
14