Тип содержимого в 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>