Заметки
Почему файл скачивается в браузере, но не через 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-эндпоинт с авторизацией на своей стороне.