2014-06-25 14 views
31

Mam problem z próbą wykonania żądania POST w mojej aplikacji i dużo szukałem, ale nie znalazłem rozwiązania.Żądanie POST jest niedozwolone - 405 niedozwolone - nginx, nawet z dołączonymi nagłówkami

Tak, mam aplikację nodeJS i strony internetowej, a ja staram się robić żądania POST za pomocą formularza z tej strony, ale zawsze kończy się w ten sposób:

enter image description here

oraz w konsola widzę:

Uncaught TypeError: Cannot read property 'value' of null 
Post "http://name.github.io/APP-example/file.html " not allowed 

że jest w tej linii kodu:

file.html:

<form id="add_Emails" method ="POST" action=""> 

    <textarea rows="5" cols="50" name="email">Put the emails here... 
    </textarea> 

     <p> 
     <INPUT type="submit" onclick="sendInvitation()" name='sendInvitationButton' value ='Send Invitation'/> 
     </p> 


</form> 

<script src="scripts/file.js"></script> 

file.js:

function sendInvitation(){ 

    var teammateEmail= document.getElementById("email").value; 

Czytałem wiele słupek i dokumentację domenach, ale to nie działa. źródło badawczy 1: http://enable-cors.org/server.html źródło badawczy 2: http://www.w3.org/TR/2013/CR-cors-20130129/#http-access-control-max-age

Co robię teraz:

Próbuję post z innej domeny mojego serwera:

POST request: http://name.github.io/APP-example/file.html, GitHub repozytorium

POST słuchacz: "http://xxx.xxx.x.xx:9000/email, serwer localhost (x-> mój adres IP)

Tak, miałem ten sam problem w innych plikach, ale naprawiłem to wprowadzenie tego kodu w begginning każdej trasy:

var express = require('express'); 
var sha1 = require('sha1'); 

var router = express.Router(); 
var sessionOBJ = require('./session'); 

var teams = {} 
var teamPlayers = [] 

router.all('*', function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*"); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    res.header("Access-Control-Allow-Methods", "PUT, GET,POST"); 
    next(); 
}); 

i naprawiłem to robi.

Teraz mam ten sam problem, ale w tym pliku jedyną różnicą jest to, że mam do czynienia z SMTP i e-mailami, więc wysyłam wiadomość e-mail i wysyłam wiadomość e-mail na tę wiadomość e-mail, którą otrzymałem w żądaniu POST.

Kod działa całkiem dobrze z POSTMAN, więc kiedy testuję z POSTMAN to działa i mogę pisać.

włączyłem ten kod poniżej zamiast pierwszego pokazałem, ale to nie działa tak dobrze:

router.all('*', function(req, res, next){ 
      res.header("Access-Control-Allow-Origin", "*") 
      res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") 
      res.header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept") 
      res.header("Access-Control-Max-Age", "1728000") 
      next(); 
     }); 

Czy ktoś wie jak go rozwiązać?

Dziękuję.

+1

Myślę, że problem występuje, ponieważ [nginx nie zezwala na POST na zawartość statyczną] (http://leandroardissone.com/post/19690882654/nginx-405-not-allowed) – Curious

+0

W jaki sposób powstaje zawartość statyczna? Czy możesz być bardziej czysty? Dziękuję za twój komentarz! :) – debeka

+3

Jeśli nginx ma określone 'location' zawiera dyrektywę' proxy_pass' lub 'fastcgi_pass', jest to zawartość dynamiczna, w przeciwnym razie - statyczna. Innymi słowy, zawartość statyczna ma miejsce, gdy nginx odczytuje plik z systemu plików i wysyła go w niezmienionym stanie. Treść dynamiczna polega na tym, że gdy określony język programowania generuje odpowiedź. Aby rozwiązać ten problem, powinieneś upewnić się, że 'lokalizacja' nginx, które obsługuje' httpxxxx.xxx.x.xx: 9000/email', zawiera 'proxy_pass' dyrektywę – Curious

Odpowiedz

39

Ta konfiguracja do pliku nginx.conf powinna ci pomóc.

https://gist.github.com/baskaran-md/e46cc25ccfac83f153bb

server { 
    listen  80; 
    server_name localhost; 

    location/{ 
     root html; 
     index index.html index.htm; 
    } 

    error_page 404  /404.html; 
    error_page 403  /403.html; 

    # To allow POST on static pages 
    error_page 405  =200 $uri; 

    # ... 
} 
+50

To jest hack, i nie starałeś się tego wyjaśnić. – nyuszika7h

+0

Wygląda na to, że po prostu przepisuje 405 na 200 - sprawiając wrażenie, jakby działało. Byłoby dobrze wiedzieć, czy to działa. to znaczy, czy zwróci statyczny zasób/ – Yehosef

+2

Wow, to działa. Ale to naprawdę nieodróżnialne od brudnego hacka. – Envek

2

To jest prawdziwa przekierowywanie proxy do zamierzonego serwerze.

server { 
    listen   80; 
    server_name  localhost; 
location/{ 
     proxy_set_header X-Real-IP $remote_addr; 
     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
     proxy_set_header X-NginX-Proxy true; 
    proxy_pass http://xx.xxx.xxx.xxx/; 
    proxy_redirect off; 
    proxy_set_header Host $host; 

    } 
} 
0

Zauważyłem, że to nie działa z konfiguracją statycznego-pierwszego-to-odwrotnego proxy. Oto, co to wygląda:

location @app { 
    proxy_pass http://localhost:3000$request_uri; 
} 

location/{ 
    try_files $uri $uri/ @app; 
    error_page 405 @app; 
} 
0

Próbowałem rozwiązanie, które przekierowuje 405 do 200, a w środowisku produkcyjnym (w moim przypadku, to Google Równoważenie obciążenia z Nginx Docker pojemniku), ten siekać powoduje jakieś 502 błędów (Kod błędu równoważenia obciążenia w usłudze Google: backend_early_response_with_non_error_status).

Ostatecznie zrobiłem to poprawnie, zamieniając Nginx na OpenResty, który jest całkowicie zgodny z Nginx i ma więcej wtyczek.

Z ngx_coolkit teraz Nginx (OpenResty) może służyć statycznych plików z post wniosek prawidłowo, tutaj jest plik config w moim przypadku:

server { 
    listen 80; 

    location/{ 
    override_method GET; 
    proxy_pass http://127.0.0.1:8080; 
    } 
} 

server { 
    listen 8080; 
    location/{ 
    root /var/www/web-static; 
    index index.html; 
    add_header Cache-Control no-cache; 
    } 
} 

W powyższej konfiguracji, używam override_method oferowanych przez ngx_coolkit przesłonić metoda HTTP do GET.