Тип содержимого в ErrorDocument

Я создаю небольшую инфраструктуру для моих API, поскольку они довольно специфичны, но у меня есть проблема с Content-Type, когда я получил данные для ErrorDocument. В настоящее время у меня есть следующий.htaccess:

<IfModule mod_headers.c>
Header set Content-Type "text/plain"
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine on

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
RewriteRule ^([a-z]+)(/[A-Za-z0-9-\._\/]*)?$ $1.php [QSA,L]

ErrorDocument 404 "API_NOT_FOUND"
</IfModule>

Чего я хочу добиться, так это ошибки 404 с другим Content-Type. Подойдет ли text/plain или application/json, но ничего из этого не работает. Поэтому, вероятно, я не могу установить заголовок Content-Type в.htaccess так, как хочу. Я также пробовал ErrorDocument в виде файла, но, поскольку путь к каталогу является динамическим, я не могу использовать документ с ошибкой без жестко заданного пути, например:

ErrorDocument 404 /api/index.php?error=404

.Htaccess находится в каталоге api, но каталог можно переименовать. Есть ли способ, которым я могу достичь одной из следующих вещей?

  • Установите Content-Type внутри.htaccess, чтобы в ErrorDocument не было текста / html с набором символов.
  • Установите документ об ошибках в index.php в каталоге.htaccess.

Если первый из них сработает, смогу ли я переопределить его внутри сценариев.php? Некоторые из моих вызовов - JSON, другие - файлы XML.

2 ответа

Решение

Спасибо за ответы и извините за окончательный ответ. Я нашел решение, которое, я думаю, работает так, как должно.

<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
</IfModule>

<IfModule mod_rewrite.c>
RewriteEngine on

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

RewriteRule ^([A-Za-z0-9_-]+)(/[A-Za-z0-9-\._\/]*)?$ $1.php [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([a-z]+) index.php?error=404 [L]
</IfModule>

Ошибка перенаправляется в index.php, который выводит правильные данные после выполнения самой регистрации, поэтому я считаю, что это беспроигрышная ситуация. Для простого объяснения следующие строки будут выполнены в index.php:

http_response_code(404);
die(json_encode(['error' => ['code' => 'API_SCRIPT_NOT_FOUND', 'number' => 404]]);

Изменить: я объясню несколько вещей, которые я делаю. Index.php обычно генерирует документацию, но когда index.php не называется чистым, я выведу ошибку notfound. Это выглядит так:

<?php
  class Documentation {}
  $API = new Documentation();

  require_once('common/initialize.php');

  Output::notfound('API_SCRIPT_NOT_FOUND');
?>

Выходной класс - это небольшой класс, который обрабатывает выходные данные с правильным Content-Type. Он автоматически устанавливает "application/json", когда не задан другой Content-Type. Небольшой пример (есть больше функций, но это тот, который он выполняет):

class Output {
    protected static $instance = null;
    public static function instance() {
        return self::$instance ?: self::$instance = new static;
    }

    private $finished = false;

    private function finish($output, $status = null) {
        if($this->finished) return; $this->finished = true;

        http_response_code($status ?: 200); $content = null;

        $headers = headers_list();
        foreach($headers as $header) {
            if(substr($header, 0, 13) == 'Content-Type:') {
                $content = substr($header, 14); break;
            }
        }

        if(!$content && !headers_sent()) {
            header(sprintf('Content-Type: %s', $content = 'application/json'));
            die(json_encode((http_response_code() >= 400) ? ['error' => $output] : $output));
        }

        die(!empty($output['code']) ? $output['code'] : $output);
    }

    public static function notfound($output) { self::instance()->finish(['code' => $output, 'number' => 404], 404); }
}

Ты можешь использовать ForceType Директива для этого.

Сначала создайте файл с именем error.json внутри вашего DocumentRoot/folder/ с этими данными:

{"error":"API_NOT_FOUND"}

Тогда в вашем DocumentRoot/folder/.htaccess иметь это так:

ErrorDocument 404 /folder/error.json
<Files "/folder/error.json">
   ForceType application/json
</Files>
Другие вопросы по тегам