2017-03-10 7 views
0

私はExpress.jsサーバーを使用しています。私は手動で私は、ブラウザのデバッグコンソールを実行しているウェブサイトは、クッキーが適用されていることを示していhttp://localhost:5555/sにブラウザを使用する場合cookie-parserで、私は、このエンドポイントにfetch()はサーバーから受信したCookieを設定できません。

app.get("/s", (req,res) => { 
    res.cookie("bsaSession", req.session.id) 
    res.send("set cookie ok") 
}) 

を開きました。

enter image description here

しかし、私は同等のものを行うにはfetch APIを使用する場合、それはクッキーを設定しません。

async trySetCookie() 
    { 
    await fetch("http://localhost:5555/s",{ 
     method: 'GET', 
     credentials: 'same-origin' 
    }) 
    } 

なぜですか?

+1

"それはクッキーを設定しません" ---どのようにそれを知っていますか?ブラウザがリクエストヘッダーにCookieを送信しましたか? – zerkms

+0

私はSafariデバッグコンソール>ストレージ> Cookiesを調べました。 'trySetCookie()'を呼び出すボタンをクリックすると、リストは変更されません。しかし、私がそのページに直接行くと、リストにはすぐに新しいクッキーが追加されます。 – 5argon

+1

それで、レスポンスヘッダに 'Set-Cookie'がありますか?そのスクリプトは同じポートで実行されますか? – zerkms

答えて

1

解決策が見つかりました。この問題の核心は、fetchをトリガーするボタンがhttp://localhost:3000/にあることです。サーバーは

問題はこのfetchコール

async trySetCookie() 
    { 
    await fetch("http://localhost:5555/s",{ 
     method: 'GET', 
     credentials: 'same-origin' 
    }) 
    } 

credentialsがなければ、ブラウザが送信またはfetchhttps://developer.mozilla.org/en-US/docs/Web/API/Request/credentials

経由でクッキーを受け取ることができないということです(私は自分のマシン上で実環境をシミュレートしています) http://localhost:5555/であります

credentialsとしてsame-origin応答ヘッダーのSet-Cookieにサーバーから送信されたCookieが表示されますが、ブラウザには何も格納されていません。 1つの奇妙なことは、サーバー上の{httpOnly : true/false}の設定にかかわらず、この応答に常にHttpOnlyがCookie文字列の後にタグ付けされていることです。 GETリクエストを行うためにページにブラウザを手動で使用する場合、いつものようにHttpOnlyが尊重され、Cookieが設定されます。

したがって、解決策は、クロスオリジンクッキー送信を可能にするために、credentialsincludeと設定することです。

app.get("/s", (req,res) => { 
    res.cookie("bsaSession", req.session.id, {httpOnly:false}) 
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000') 
    res.header('Access-Control-Allow-Credentials','true' 
    res.send("set") 
}) 

XMLHttpRequest cannot load http://localhost:5555/s. Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.

しかし、クッキーの意志になり、これをやっていない:あなたは新しいヘッダを使って手動で特定の起源を許可する必要があり、サーバー側でも

async trySetCookie() 
    { 
    await fetch("http://localhost:5555/s",{ 
     method: 'GET', 
     credentials: 'include' 
    }) 
    } 

、このエラーに関係なく設定してください。そのヘッダーをインクルードしてエラーを無音にしてもいいです。

Expresscorsミドルウェアを使用している場合は、さらに簡単です。あなただけの

var corsOptions = { 
    origin: 'http://localhost:3000', 
    credentials: true 
} 

app.use(cors(corsOptions)) 

そしてもちろんcredentials: 'include'のこれらのオプションを使用することができ、まだクライアント側で必要とされます。

関連する問題