Django:如何将用户上传的HTML文件MIME类型改为text/plain?
解决Django中HTML附件以text/plain类型返回的方法
下面是几个实用方案,能确保用户上传的HTML文件作为纯文本源代码展示,而非被浏览器渲染成网页:
方案一:自定义文件存储类,修改Content-Type
在文件保存阶段就修改HTML文件的内容类型,后续访问时默认返回text/plain。
创建自定义Storage类,继承Django的FileSystemStorage并重写_get_content_type方法:
# 你的app目录下新建storage.py from django.core.files.storage import FileSystemStorage class PlainTextHTMLStorage(FileSystemStorage): def _get_content_type(self, name, content): content_type = super()._get_content_type(name, content) # 对所有.html后缀的文件强制返回text/plain if name.lower().endswith('.html'): return 'text/plain' return content_type
在模型的FileField中使用这个存储类:
# models.py from django.db import models from .storage import PlainTextHTMLStorage class Post(models.Model): # 其他字段... html_attachment = models.FileField( storage=PlainTextHTMLStorage(), upload_to='post_attachments/' )
方案二:自定义视图处理文件访问,手动设置响应头
如果不想修改存储逻辑,可通过自定义视图接管文件访问请求,在响应里强制指定Content-Type。
编写视图函数:
# views.py from django.http import FileResponse from django.shortcuts import get_object_or_404 from .models import Post import os def serve_html_as_plaintext(request, post_id): post = get_object_or_404(Post, id=post_id) file_obj = post.html_attachment response = FileResponse(file_obj.open('rb')) # 强制设置内容类型为纯文本 response['Content-Type'] = 'text/plain' # 可选:让浏览器直接显示而非下载文件 response['Content-Disposition'] = f'inline; filename="{os.path.basename(file_obj.name)}"' return response
配置对应路由:
# urls.py from django.urls import path from .views import serve_html_as_plaintext urlpatterns = [ # 其他路由... path('post/<int:post_id>/html-attachment/', serve_html_as_plaintext, name='serve_html_plaintext'), ]
方案三:生产环境静态文件服务器配置(推荐)
如果项目用Nginx等服务器托管媒体文件,直接在服务器配置中给.html文件指定Content-Type,效率更高:
location /media/ { alias /你的媒体文件存储路径/; # 匹配所有.html后缀文件,强制返回text/plain location ~* \.html$ { types { } default_type text/plain; } }
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

