← Назад к заметкам

Заметки

Почему файл скачивается в браузере, но не через file_get_contents

Почему ссылка на файл открывается в браузере, но не скачивается серверным PHP-кодом: cookie, авторизация, access token и публичные ссылки.

Если файл открывается в браузере, это ещё не значит, что URL можно скачать серверным скриптом. Браузер использует пользовательскую сессию, а `file_get_contents` — нет. Для интеграций лучше идти через REST, access token, публичную ссылку или свой backend.

Проблема

Бывает, что сотрудник открывает файл по ссылке в браузере, а серверный скрипт через file_get_contents получает пустой ответ, HTML авторизации или ошибку доступа.

Причина почти всегда в контексте доступа. Браузер идёт со своей сессией, cookie и правами пользователя. Серверный PHP-скрипт идёт как отдельный клиент, у которого этих cookie нет.

Авторизация и cookie

Если URL ведёт на закрытый файл портала, он может работать только для авторизованного пользователя. В браузере это незаметно, потому что сессия уже есть.

$content = file_get_contents('https://portal.example.ru/path/to/file');

if ($content === false) {
    echo 'Файл не скачался';
}

Такой код не передаёт пользовательскую сессию и не доказывает Битриксу, что имеет право читать файл.

Как скачивать правильно

Для интеграции лучше не копировать URL из браузера, а получать файл через REST с токеном или создавать публичную ссылку Диска.

$ch = curl_init('https://portal.example.ru/rest/disk.file.get');

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer access_token_here',
    ],
    CURLOPT_POSTFIELDS => http_build_query([
        'id' => 9043,
    ]),
]);

$response = curl_exec($ch);
curl_close($ch);

echo $response;

Если файл нужно отдать внешней системе без авторизации в Битрикс24, используйте публичную ссылку Диска или свой серверный обработчик, который проверит права и аккуратно отдаст файл.

Публичная ссылка

Публичная ссылка решает проблему cookie, но меняет модель доступа: файл смогут открыть те, у кого есть ссылка. Для внутренних документов это может быть лишним.

BX24.callMethod(
    'disk.file.getExternalLink',
    { id: 9043 },
    function (result) {
        console.log(result.data());
    }
);

Для одноразовых интеграций безопаснее часто делать не постоянную публичную ссылку, а контролируемый backend-эндпоинт с авторизацией на своей стороне.