Kaip leisti CORS?

Bandau palaikyti CORS mano „Node.js“ programoje, kuri naudoja „Express.js“ žiniatinklio sistemą. Perskaičiau „Google“ grupės diskusiją apie tai, kaip elgtis, ir skaityti keletą straipsnių apie tai, kaip veikia CORS. Pirma, tai padariau (kodas parašytas „CoffeeScript“ sintaksėje):

 app.options "*", (req, res) -> res.header 'Access-Control-Allow-Origin', '*' res.header 'Access-Control-Allow-Credentials', true # try: 'POST, GET, PUT, DELETE, OPTIONS' res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS' # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept' res.header 'Access-Control-Allow-Headers', 'Content-Type' # ... 

Atrodo, jis neveikia. Atrodo, kad mano naršyklė („Chrome“) nesiunčia pradinio OPTIONS užklausos. Kai ką tik atnaujinau išteklių bloką, turiu siųsti GET užklausą su kryžminiu paleidimu:

 app.get "/somethingelse", (req, res) -> # ... res.header 'Access-Control-Allow-Origin', '*' res.header 'Access-Control-Allow-Credentials', true res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS' res.header 'Access-Control-Allow-Headers', 'Content-Type' # ... 

Jis veikia („Chrome“). Tai taip pat veikia „Safari“.

Aš perskaičiau, kad ...

Naršyklėje, diegiančioje CORS, kiekvienam GET arba POST prašymui pradėti kryžminį paleidimą yra pateiktas prašymas OPTIONS, kuris patikrina, ar GET arba POST yra gerai.

Taigi mano pagrindinis klausimas: kodėl taip nėra mano atveju? Kodėl mano „app.options“ blokas neskambinamas? Kodėl reikia nustatyti antraštes pagrindiniame „app.get“ bloke?

533
15 авг. nustatyti mikong 15 rug . 2011-08-15 19:53 '11, 19:53, 2011-08-15 19:53
@ 23 atsakymai

Norint atsakyti į jūsų pagrindinį klausimą, CORS specifikacija reikalauja, kad prieš skambinant „POST“ arba „GET“ būtų sudėtingas turinys arba antraštės.

Turinio tipai, kuriems reikalingas CORS prašymas prieš skrydį (OPTIONS skambutis), yra bet kokio pobūdžio turinys, išskyrus šiuos:

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

Bet kokie turinio tipai, išskyrus pirmiau išvardytus, sukels užklausą dėl išankstinio nustatymo.

Kalbant apie antraštes, bet kuri kita užklausų antraštė, išskyrus toliau pateiktą, sukels užklausą dėl žodžio:

  1. Accept
  2. Accept->
  3. Content->
  4. Content-Type
  5. DPR
  6. Save-Data
  7. Viewport-Width
  8. Width

Bet kuri kita užklausos antraštė įjungia užklausą dėl preflight.

Taigi, galite pridėti priskirtą antraštę, pavyzdžiui: x-Trigger: CORS , ir tai turėtų paskatinti išankstinio vaizdo užklausą ir patekti į OPTIONS bloką.

Žr. MDN žiniatinklio API nuorodą - Pre-CORS užklausos.

117
20 дек. Atsakymą pateikė Dobes Vandermeer . 2011-12-20 11:32 '11, 11:32, 2011-12-20 11:32

Radau lengviausią būdą naudoti node.js cors paketą. Paprasčiausias naudojimas:

 var cors = require('cors') var app = express() app.use(cors()) 

Žinoma, yra daug būdų, kaip pritaikyti elgesį pagal jūsų poreikius; Pirmiau pateiktame puslapyje pateikiami keli pavyzdžiai.

584
07 февр. Wayne Maurer atsakymas 07 Feb. 2014-02-07 11:16 '14 at 11:16 2014-02-07 11:16

Pabandykite perkelti valdiklį į kitą tinkamą maršrutą. Jei „Express“ pirmą kartą atitinka „app.get“ maršrutą, tuomet jis nebus tęsiamas į parinkčių kelią, jei to nepadarysite (atkreipkite dėmesį į tai, kad naudojate šiuos dalykus):

 app.get('somethingelse', function(req, res, next) { //..set headers etc. next(); }); 

Kalbant apie CORS medžiagos organizavimą, aš ją įdėjau į tarpinę programinę įrangą, kuri gerai veikia man:

 //CORS middleware var allowCrossDomain = function(req, res, next) { res.header('Access-Control-Allow-Origin', 'example.com'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); } //... app.configure(function() { app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session({ secret: 'cool beans' })); app.use(express.methodOverride()); app.use(allowCrossDomain); app.use(app.router); app.use(express.static(__dirname + '/public')); }); 
414
15 авг. atsakymas pateikiamas piktadariai 15 d. 2011-08-15 22:45 '11 10:45 val. 2011-08-15 22:45

Būkite ta pačia maršruto idėja. Naudoju šį kodą:

 app.all(' let server = express(); server.set('port', 3000);  server.use('/somethingElse', function(req, res) { let url = proxyConfig.url.base + req.query.id; req.pipe(request(url)).pipe(res); });  server.listen(server.get('port'), function() { console.log('express server with a proxy listening on port ' + server.get('port')); }); 
2
10 февр. atsakymas, kurį pateikė melvinv 10 vasaris 2016-02-10 16:06 '16 at 16:06 2016-02-10 16:06

Naudojant „Express Middleware“, man puikiai tinka. Jei jau naudojate „Express“, tiesiog pridėkite šias tarpinės programinės įrangos taisykles. Jis turi pradėti dirbti.

 app.all("/api import * as express from "express"; [...] import * as cors from 'cors'; class App { public express: express.Application; constructor() { this.express = express(); [..] this.handleCORSErrors(); } private handleCORSErrors(): any { const corsOptions: cors.CorsOptions = { origin: 'http://example.com', optionsSuccessStatus: 200 }; this.express.use(cors(corsOptions)); } } export default new App().express; 

Jei nenorite naudoti trečiosios šalies bibliotekų, kad tvarkytumėte „Cors“ klaidas, turite keisti rankenosCORSErrors () metodą.

  import * as express from "express"; [...] class App { public express: express.Application; constructor() { this.express = express(); [..] this.handleCORSErrors(); } private handleCORSErrors(): any { this.express.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); res.header( "Access-Control-ALlow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization" ); if (req.method === "OPTIONS") { res.header( "Access-Control-Allow-Methods", "PUT, POST, PATCH, GET, DELETE" ); return res.status(200).json({}); } next(); // send the request to the next middleware }); } } export default new App().express; 

Norėdami naudoti „app.ts“ failą

  import * as http from "http"; import app from "./app"; const server: http.Server = http.createServer(app); const PORT: any = process.env.PORT || 3000; server.listen(PORT); 
-1
09 июля '18 в 12:41 2018-07-09 12:41 atsakymas pateikiamas perėmėjas liepos 9 d. 18 d. 12:41 val. 2018-07-09 12:41

Žemiau pateikiamas kodas, bet pirmiausia įdiegiami kodai:

npm įdiegti - išsaugoti korpusą

Tada:

 module.exports = function(app) { var express = require("express"); var cors = require('cors'); var router = express.Router(); app.use(cors()); app.post("/movies",cors(), function(req, res) { res.send("test"); }); 
-1
02 окт. atsakymas suteiktas BCool 02 okt. 2018-10-02 16:40 '18, 4:40 pm 2018-10-02 16:40

Kiti klausimai apie „ žymes arba klausimą