Назад | Перейти на главную страницу

nginx proxy_pass получает заголовки содержимого / статуса, когда http 4xx

Возникли проблемы, описанные здесь - https://stackoverflow.com/questions/22570550/play-2-2-1-simpleresult-4xx-response-body-possible-via-cors-xhr

Но я не сосредотачивался на nginx, так как счастливый путь 200 OK работал должным образом. Это были ошибки HTTP 400 уровня, которые не работали должным образом. Я не получал тело или не мог получить код состояния внутри XHR-объектов браузера.

Ошибки HTTP 4xx работали как ожидалось через XHR (readyState = 3 опытных) только когда я передавал Access-Control-Allow-Origin с сервера приложений, но я не хочу, чтобы это было встроено в код.

Единственный способ передать заголовки содержимого и статуса для ответов 4xx - это скомпилировать с ЗаголовкиБольшеNginxModule? Не идеально, но выполнимо.

package controllers

import play.api._
import play.api.mvc._
import play.api.libs.iteratee.Enumerator

object Application extends Controller {

  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }

  def goodResponse = Action { implicit request =>
    // Ok("Hello world!")
    SimpleResult(
      header = ResponseHeader(200, Map(CONTENT_TYPE -> "application/json")),
      body = Enumerator("Hello world!".getBytes())
    )
  }

  def badResponse = Action { implicit request =>
    // BadRequest(
    //   """{"error":"bad request"}"""
    // )
    SimpleResult(
      header = ResponseHeader(
        400, 
        Map(
          CONTENT_TYPE -> "application/json",
          ACCESS_CONTROL_ALLOW_ORIGIN -> "*"     // FIXME: move to nginx?
        )
      ),
      body = Enumerator("""{"error":"bad request"}""".getBytes())
    )
  }

}

Мой nginx.conf использует proxy_pass для игрового сервера на порту 9000:

http {

  # ...snipped...

  upstream api {
    server localhost:9000;
  }

  server {
    #listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default ipv6only=on; ## listen for ipv6
    listen 80;
    listen 443 default_server ssl;
    ssl_certificate      /usr/local/etc/nginx/ssl/api.crt;
    ssl_certificate_key  /usr/local/etc/nginx/ssl/nginx.key;

    root /usr/share/nginx/www;
    index index.html index.htm;

    # Make site accessible from https://api/
    server_name api;

    location / {
      # See http://enable-cors.org/server_nginx.html
      # Modified to set 'Access-Control-Allow-Origin' "$http_origin"
      include nginx_cors.conf;

      proxy_pass http://api;

    }

  }
}

Проверьте всю конфигурацию nginx и убедитесь, что вы не установили proxy_intercept_errors on; где-то. Этот параметр должен быть off в вашем сценарии.