HTTP-ответ состоит из заголовков и тела, разделенных первым полученным \r\n\r\n
. К тому времени, когда веб-сервер отправляет обычный файл, он уже отправил все заголовки и разделитель.
Однако при запуске сценария заголовки не отправляются автоматически.
Итак, в первом случае ваш веб-сервер угадал тип содержимого по расширению и отправил соответствующие заголовки перед отправкой содержимого файла. Во втором сценарий отправляет переопределяющий заголовок для типа содержимого. Затем веб-сервер решает, как это сделать, с точки зрения вставки других стандартных заголовков http.
EDIT:
Apache использует mod_mine и /etc/mime.types для сопоставления расширений файлов с типами содержимого. Вероятно, по умолчанию это text / plain для всего, что не имеет расширения, которое оно понимает.
Возможно, браузер отключит расширение, только если у него нет типа содержимого для использования.
Предполагается, что простые файлы содержат только данные, а заголовки генерируются веб-сервером, в то время как сценарии cgi ожидают / могут генерировать свои собственные заголовки.