Ich habe die Lösung gefunden. Der Kern dieses Problems ist, dass meine Taste zum Auslösen der fetch
auf http://localhost:3000/
ist. Der Server ist auf http://localhost:5555/
(ich auf meinem eigenen Rechner reale Umgebung bin simuliert)
Das Problem ist, dass dieser fetch
Aufruf
async trySetCookie()
{
await fetch("http://localhost:5555/s",{
method: 'GET',
credentials: 'same-origin'
})
}
Ohne credentials
, kann der Browser keine Cookies über fetch
(https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials)
senden oder empfangen
Mit credentials
als same-origin
kann ich die Cookies vom Server in der Set-Cookie
Antwort Header sehen, aber nichts wird im Browser gespeichert. Eine seltsame Sache ist, dass diese Antwort immer HttpOnly
nach der Cookie-Zeichenfolge unabhängig von meiner {httpOnly : true/false}
Einstellungen auf dem Server getaggt haben. Im Fall der manuellen Verwendung des Browsers für die Seite, die die GET-Anfrage durchführt, wird HttpOnly
wie üblich respektiert und die Cookies werden gesetzt.
Die Lösung besteht also darin, credentials
als include
so zu setzen, dass Cross-Origin-Cookies gesendet werden können.
async trySetCookie()
{
await fetch("http://localhost:5555/s",{
method: 'GET',
credentials: 'include'
})
}
Auch auf der Server-Seite müssen Sie eine bestimmte Herkunft ermöglichen, manuell mit neuen Header:
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")
})
Nicht dies führt zu
tun
XMLHttpRequest cannot load http://localhost:5555/s. Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
Aber das Cookie unabhängig von diesem Fehler gesetzt werden. Es ist immer noch schön, diesen Header einzuschließen, um den Fehler zum Schweigen zu bringen.
Wenn Sie cors
Middleware für Express
verwenden, ist es noch einfacher. Sie können nur diese Optionen verwenden
var corsOptions = {
origin: 'http://localhost:3000',
credentials: true
}
app.use(cors(corsOptions))
Und natürlich credentials: 'include'
noch auf der Client-Seite erforderlich ist.
"Es setzt den Cookie nicht" --- Woher weißt du das? Hat der Browser den Cookie in den Anforderungsheadern gesendet? – zerkms
Ich schaute in der Safari-Debug-Konsole> Speicher> Cookies. Wenn ich auf den Knopf klicke, der 'trySetCookie()' aufruft, ändert sich die Liste nicht. Aber wenn ich direkt auf diese Seite gehe, werden sofort neue Cookies hinzugefügt. – 5argon
Also, siehst du den 'Set-Cookie' in den Antwortheadern? Wird dieses Skript auf demselben Port ausgeführt? – zerkms