Задать вопрос
@spido

Как выдать ошибку 410 странице, если в середине ссылки есть знак вопроса?

Приветствую!

Есть ссылки, которым нужно присвоить ошибку 410, если в середине ссылки имеется знак вопроса:
https://mysite.com/ru?khl-service=
https://mysite.com/en?gdf-service=
https://mysite.com/es-mx?opl-service=


Сделал условие:
use Illuminate\Support\Str;

if (Str::contains(request()->getRequestUri(), '?')) {
 header("HTTP/1.1 410 Gone");// Сообщаем браузеру, что страница удалена по коду 410 Gone
 exit;		
}

Но условие не работает.

Дело ещё в том, что я использую кэширование страниц с помощью https://github.com/JosephSilber/page-cache
Пакет кэширования создает папку со статическими файлами и отдает их через правила сервера nginx:

location = / {
    try_files /page-cache/pc__index__pc.html /index.php$is_args$query_string;
}
location / {
    try_files $uri $uri/ /page-cache/$uri.html /page-cache/$uri.json /page-cache/$uri.xml /index.php$is_args$query_string;
}


В итоге, nginx отдает страницу из кеша, которая имеет адрес ссылки до знака вопроса, а не страницу с ошибкой 410.
Если я выключаю использование кэша, то правило PHP Laravel работает как надо.

Вот примеры страниц которых не существует и нужно получить ошибку 410:
https://mysite.com/ru?khl-service=
https://mysite.com/en?gdf-service=
https://mysite.com/es-mx?opl-service=

Эти страницы существуют и записываются в кэш с кодом 200:
https://mysite.com/ru
https://mysite.com/en
https://mysite.com/es-mx

Если открыть ссылку в браузере https://mysite.com/ru?khl-service=, то сервер отдает страницу из кэша https://mysite.com/ru.
При этом ссылка в строке браузера всё та же https://mysite.com/ru?khl-service=.

Создал файл и прописал отключить кэширование ссылки со знаком вопроса. Не работает именно правило для знака вопроса. Для других страниц правило работает, где нет сохраненной в кэше страницы с адресом до знака вопроса.
<?php

namespace App\Http\Middleware;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Str;
use Silber\PageCache\Middleware\CacheResponse as BaseCacheResponse;

class CacheResponse extends BaseCacheResponse
{
    protected function shouldCache(Request $request, Response $response)
    {			
		// Исключаем сохранение кэша если ссылка содержит /admin
		} elseif (Str::contains(request()->getRequestUri(), '/admin')) {
			return false;
			
		// Исключаем сохранение кэша если ссылка содержит предварительный просмотр страницы в админке ?preview=true
		} elseif (Str::contains(request()->getRequestUri(), '?preview=true')) {
			return false;
				
		// Исключаем сохранение кэша если ссылка содержит знак вопроса
		} elseif (Str::contains(request()->getRequestUri(), '?')) {
			return false;
			
		} else {
			return $request->isMethod('GET') && $response->getStatusCode() == 200;
		}
		
        return parent::shouldCache($request, $response);
    }
}


Что-то нужно делать с правилом для сервера nginx. Только я не знаю что.

Подскажите как сделать правильно?
  • Вопрос задан
  • 115 просмотров
Подписаться 1 Простой 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
RusPOPsy
@RusPOPsy
Говорила мама, учи математику ...
Где условие то разместили?
Вообще то должно работать, только "exit" не надо делать в Laravel.

Правильнее будет через Middleware
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;

class UriIsGone
{
    public function handle(Request $request, Closure $next): Response
    {
        if (Str::contains(request()->getRequestUri(), '?')) {
            return \response("Gone error", 410);
        }
        return $next($request);
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы