2013-08-28 18 views
10

Jestem w trakcie przebudowywania aplikacji PHP w Node.js na platformie Express.W jaki sposób uzyskujesz dostęp do treści posta w usłudze Amazon SNS za pomocą Express/Node.js

Jedną z części aplikacji jest URL wywołania zwrotnego, do którego wysłano numer Amazon SNS notification.

Ciało POST z SNS jest obecnie czytać w następujący sposób w PHP (które działa):

$notification = json_decode(file_get_contents('php://input')); 

Ekspresowe Próbowałem następujące:

app.post('/notification/url', function(req, res) { 
    console.log(req.body); 
}); 

Jednak obserwując konsolę , rejestruje się tylko następujące informacje po utworzeniu wpisu:

{} 

Aby powtórzyć zadanie ion: W jaki sposób uzyskujesz dostęp do treści pocztowej w usłudze Amazon SNS za pomocą Express/Node.js

+0

Jako kontekst: przyczyną niepowodzenia tego (uzasadnionego, naiwnego) podejścia jest ustawienie HTTP SNS. "Content-Type: text/plain; charset = UTF-8" Zobacz: http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html (SNS tak naprawdę nie grokuje JSON) – Jason

Odpowiedz

22

Innym rozwiązaniem byłoby ustalenie Content-Type nagłówek.

Oto kod middleware, aby to zrobić:

exports.overrideContentType = function(){ 
    return function(req, res, next) { 
    if (req.headers['x-amz-sns-message-type']) { 
     req.headers['content-type'] = 'application/json;charset=UTF-8'; 
    } 
    next(); 
    }; 
} 

Zakłada znajduje się plik o nazwie util.js znajdujące się w katalogu projektu z korzenia:

util = require('./util'); 

w twojej aplikacja.js i powoływać w tym:

app.use(util.overrideContentType()); 

PRZED

app.use(express.bodyParser()); 

w app.js pliku. Pozwala bodyParser() do analizowania organizmowi prawidłowo ...

mniej inwazyjne, a następnie można uzyskać dostęp req.body normalnie.

+2

To jest świetna odpowiedź, szczególnie jeśli chcesz używać tej samej aplikacji do przetwarzania powiadomień i potwierdzeń subskrypcji z SNS. – supaseca

+0

http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.html#SendMessageToHttp.prepare Czy istnieje powód, dla którego AWS używa "text/plain' jako Content-Type? To był prawdziwy ból głowy z tym związany. Cieszę się, że istnieje rozwiązanie tam – lasec0203

+0

Spójrz na [ten temat] (https://forums.aws.amazon.com/thread.jspa?threadID=69413) i wyciągnij własne wnioski. Uważaj na daty. Zamiast próbować znaleźć rozwiązania alternatywne, aby obejść problem, lepiej byłoby, gdyby AWS to naprawił. – Talma

3

Spójrz na AWS Node.js SDK - może uzyskać dostęp do wszystkich punktów końcowych usługi AWS.

var sns = new AWS.SNS(); 

    // subscribe 
    sns.subscribe({topic: "topic", Protocol: "https"}, function (err, data) { 
     if (err) { 
     console.log(err); // an error occurred 
     } else { 
     console.log(data); // successful response - the body should be in the data 
    } 
    }); 


    // publish example 
    sns.publish({topic: "topic", message: "my message"}, function (err, data) { 
     if (err) { 
     console.log(err); // an error occurred 
     } else { 
     console.log(data); // successful response - the body should be in the data 
    } 
    }); 

EDIT: Problem polega na tym, że standard parser organizm nie radzi sobie zwykły/tekstu, który jest co SNS wysyła jako typ zawartości. Oto kod do wyodrębnienia surowego ciała. Umieścić go przed parsera ciała:

app.use(function(req, res, next) { 
    var d= ''; 
    req.setEncoding('utf8'); 
    req.on('d', function(chunk) { 
     d+= chunk; 
    }); 
    req.on('end', function() { 
     req.rawBody = d; 
     next(); 
    }); 
}); 

Następnie można użyć:

JSON.stringify(req.rawBody)); 

ciągu trasy stworzyć JavaScript Object i działają na SNS zakładać odpowiednio.

Można również zmodyfikować analizator treści, aby obsługiwał tekst/zwykły, ale nie jest to świetny pomysł na modyfikowanie oprogramowania pośredniego. Po prostu użyj powyższego kodu.

+0

Myślę, że to może być etap wcześniej. Moja aplikacja jest już subskrybowana. SNS wysyła do niego informację, ponieważ widzę ją w konsoli, ale nie mogę uzyskać dostępu do treści postu. – timstermatic

+1

Ah, mam to, przepraszam. Rozumiem teraz, co robisz. Uważam, że SNS wysyła treść jako tekst/zwykły, nawet jeśli tekst jest w formacie JSON. Jak skonfigurowałeś parsery ciała? Standardowy analizator składni obsługuje tylko application/json, application/x-www-form-encoded i multipart/form-data. Dodałem kod powyżej, aby umieścić go przed analizatorem treści. Da ci to surowiec z twojej prośby, który możesz przetestować, aby upewnić się, że otrzymujesz dane z SNS. Zaloguj się, a następnie możesz napisać własny parser ciała. – AlexGad

+0

Nie mogłem tego uruchomić. Jednak wskazało mi to w dobrym kierunku z wymaganiem i kawałkiem, więc dziękuję za wkład. Postawiłem moje rozwiązanie jako zaakceptowaną odpowiedź. – timstermatic

5

ta opiera się na AlexGad za answer.Particularly ten komentarz:

Standardowa express parser zajmie tylko application/json, application/x-www-form-zakodowane multipart/form-data. Dodałem kod powyżej, aby umieścić go przed analizatorem treści.

app.post('/notification/url', function(req, res) { 
    var bodyarr = [] 
    req.on('data', function(chunk){ 
     bodyarr.push(chunk); 
    }) 
    req.on('end', function(){ 
     console.log(bodyarr.join('')) 
    }) 
}) 
+0

Pod względem technicznym, wyższy głosowanie jest "czystszym" rozwiązaniem wskazanego problemu. Niech dobrze przetestowany framework wykona zadanie ... – andreas

Powiązane problemy