Heroku'da bir Express / Node.js uygulamasına CORS REST isteğine izin ver


98

Chrome'daki js konsolundan ve URL çubuğundan vb. Gelen istekler için çalışan node.js için ekspres çerçeve üzerine bir REST API yazdım. Şimdi başka bir uygulamadan gelen istekler için başka bir uygulamada çalışmasını sağlamaya çalışıyorum. etki alanı (CORS).

Javascript ön ucu tarafından otomatik olarak yapılan ilk istek, / api / search? Uri = içindir ve "ön kontrol" SEÇENEKLERİ isteğinde başarısız görünüyor.

Ekspres uygulamamda, aşağıdakileri kullanarak CORS başlıkları ekliyorum:

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
      res.send(200);
    }
    else {
      next();
    }
};

ve:

app.configure(function () {
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(allowCrossDomain);
  app.use(express.static(path.join(application_root, "public")));
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

Chrome konsolundan şu başlıkları alıyorum:

İstek URL'si: http: //furious-night-5419.herokuapp.com/api/search? Uri = http% 3A% 2F% 2Flocalhost% 3A5000% 2Fcollections% 2F1% 2Fdocuments% 2F1

İstek Yöntemi: SEÇENEKLER

Durum Kodu: 200 Tamam

Üstbilgi İste

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, x-annotator-auth-token, accept
Access-Control-Request-Method:GET
Connection:keep-alive
Host:furious-night-5419.herokuapp.com
Origin:http://localhost:5000
Referer:http://localhost:5000/collections/1/documents/1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5

Sorgu Dizesi Parametreleri

uri:http://localhost:5000/collections/1/documents/1

Yanıt Başlıkları

Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
X-Powered-By:Express

Bu, API uygulaması tarafından gönderilen uygun başlıkların eksikliği gibi görünüyor mu?

Teşekkürler.


Bu hatayı yazmadığım bir kodda alıyorum, ancak OPTIONSyöntem için bir işleyicinin ihtiyacını anlamıyorum . Birisi sadece uğraşmak yerine neden anlamama yardım eder misiniz POSTyöntemi yerine hem taşıma POST ve OPTIONS yöntemi?
Ulysses Alves

Bir kaynağı güncellemek PATCHyerine onu kullanıp kullanmayacağınızı da eklemek isteyebilirsinizPUT
Danny

Yanıtlar:


66

Kodunuzu temiz bir ExpressJS uygulamasında kontrol ettim ve gayet iyi çalışıyor.

app.use(allowCrossDomain)Yapılandırma işlevinin en üstüne taşımayı deneyin .


8
Bunun nedeni, onu Cheers'dan önce tanımlamanız gerektiğidir app.use(app.router);!
Michal

Benim durumumda, req.method == 'OPTIONS' olduğunda res.send (200) geri gönderildikten sonra sonraki POST çağrılmıyor. başka bir şey eksik mi
Aldo

2Aldo: Kod gerekli. Bazı başlıkları unutmuş olabilirsiniz. Sunucunuza doğru bir şekilde ön kontrol SEÇENEKLERİ isteği gönderildikten sonra istemciniz bir POST göndermiyorsa, geliştirici araçları konsolunu kontrol etmeyi deneyin. WebKit, bu tür hataları web denetçisinin konsoluna kaydeder.
Olegas

1
@ConnorLeech Çok güzel. Yukarıdaki gibi allowCrossDomain yaklaşımını uyguluyordum ve tüm bu başlık yönetimiyle uğraşmaktan yorulmuştum. Ayrıca - geliştirme için yalnızca CORS'a ihtiyacımız olduğundan, neler olup bittiğini anlamaya bu kadar çok döngü ayırmak mantıklı gelmiyordu. Buna kolayca izin vermek için node.js desteği olmasına sevindim.
Steven

1
@ConnorLeech Yorumunuzu yanıt olarak eklemeniz gerektiğini düşünüyorum ... bir tedavi gibi çalışıyor ve hoş ve basit
drmrbrewer

4

Tanımlama bilgileriyle tanımlama bilgilerini desteklemek için bu satıra ihtiyacınız var xhr.withCredentials = true;

mdn docs xhr.withCredentials

Express Server'da bu bloğu diğerlerinin hepsinden önce ekleyin

`app.all('*', function(req, res, next) {
     var origin = req.get('origin'); 
     res.header('Access-Control-Allow-Origin', origin);
     res.header("Access-Control-Allow-Headers", "X-Requested-With");
     res.header('Access-Control-Allow-Headers', 'Content-Type');
     next();
});`

4

Bunu bir cevap olarak ekliyorum çünkü orijinal gönderi yorum olarak eklendi ve bu nedenle bu sayfaya ilk kez girdiğimde gerçekten sizin tarafınızdan gözden kaçtı.

@ConnorLeech'in yukarıdaki kabul edilen cevaba yaptığı yorumda işaret ettiği gibi, şaşırtıcı olmayan bir şekilde cors adında çok kullanışlı bir npm paketi var . Kullanımı kadar basittir var cors = require('cors'); app.use(cors());(yine Bay Leech'in cevabından alınmıştır) ve ayrıca belgelerinde belirtildiği gibi daha katı, daha yapılandırılabilir bir şekilde de uygulanabilir .

Yukarıda bahsettiğim orijinal yorumun 2014 yılında yapıldığını da belirtmekte fayda var. Şu an 2019 ve npm paketinin github sayfasına bakıldığında repo dokuz gün önce güncellendi.


0

Bu soruya göz atan çoğu insan için durum böyle olamazdı, ancak aynı sorunu yaşadım ve çözüm bununla ilgili değildi CORS.

JSON Web Token sırrının stringortam değişkenlerinde tanımlanmadığı, bu nedenle belirteç imzalanamadığı ortaya çıktı. Bu POST, bir zaman aşımı elde etmek ve bir 503hata döndürmek için bir belirteci kontrol etmeye veya imzalamaya dayanan herhangi bir isteğe neden oldu ve tarayıcıya yanlış bir şey olduğunu CORS, öyle olmadığını söyledi. Heroku'da ortam değişkenini eklemek sorunu çözdü.

Umarım bu birine yardımcı olur.


Evet benim sorunum buydu. Problemi nasıl çözdüğünüzü biraz daha açıklayabilir misiniz? Hala geliştirme aşamasındayım ve Express.js w / node cors paketi üzerinde çalışıyorum.
Alan

@alan Uygulamamda belirteci doğrulamak için sözler kullanıyordum, bazıları JWT sırrı tanımlanmazsa, söz asla çözülmez, daha fazla referansa ihtiyacınız varsa burada kullandığım kod .
CatBrownie

Cevap verdiğiniz için teşekkürler. Kod üzerinden bakacağım. Gizli olarak, ikinci özel anahtar hakkında konuştuğunuzu varsayıyorum. Oauth2 kullanıyorum.
Alan

Herhangi bir başarısız sözün bu yanıltıcı hatayı üreteceğini ekleyeceğim! Kullanılmakta olan bir Node sürümü hakkında açık olmalıydım ya da veritabanı aramalarım (mongo) basitçe takılıyordu ve tarayıcının bana söyleyebileceği tek şey 503 ve ardından Cors ile ilgili bir saçmalıktı. Bu hata, app.use(cors());devam ettiğim en uzun süre kafamı gerçekten karıştırdı .
alphanumeric0101

0

görüntü açıklamasını buraya girin

Aşağıdaki adımları izleyin:

npm kurulum cors --save

Kök js dosyanızın içinde:

 var express = require('express') 
 var cors = require('cors')
 var app = express()
 app.use(cors())
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.