在处理文件下载并设置 Content-Type
时,可以根据你所使用的后端技术(例如,Java Spring、Node.js、Django 等)进行设置。一般情况下,你可以根据文件类型或扩展名自动设置合适的 Content-Type
。
下面我将介绍如何在一些常见的后端框架中实现这个功能。
1、问题背景
在 App Engine 中,我遇到了一个问题,即如何在我下载我上传的数据时自动设置 Content-Type。我的代码如下:
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
#from login import htmlPrefix,get_current_user
class MyModel(db.Model):
blob = db.BlobProperty()
class BaseRequestHandler(webapp.RequestHandler):
def render_template(self, filename, template_args=None):
if not template_args:
template_args = {}
path = os.path.join(os.path.dirname(__file__), 'templates', filename)
self.response.out.write(template.render(path, template_args))
class upload(BaseRequestHandler):
def get(self):
self.render_template('index.html',)
def post(self):
file=self.request.get('file')
obj = MyModel()
obj.blob = db.Blob(file.encode('utf8'))
obj.put()
self.response.out.write('upload ok')
class download(BaseRequestHandler):
def get(self):
#id=self.request.get('id')
o = MyModel.all().get()
#self.response.out.write(''.join('%s: %s <br/>' % (a, getattr(o, a)) for a in dir(o)))
self.response.out.write(o)
application = webapp.WSGIApplication(
[
('/?', upload),
('/download',download),
],
debug=True
)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
My index.html is :
<form action="/" method="post">
<input type="file" name="file" />
<input type="submit" />
</form>
And it show :
<__main__.MyModel object at 0x02506830>
But I don't want to see this, I want to download it.
How to change my code to run?
Thanks
updated
It is ok now :
class upload(BaseRequestHandler):
def get(self):
self.render_template('index.html',)
def post(self):
file=self.request.get('file')
obj = MyModel()
obj.blob = db.Blob(file)
obj.put()
self.response.out.write('upload ok')
class download(BaseRequestHandler):
def get(self):
#id=self.request.get('id')
o = MyModel.all().order('-').get()
#self.response.out.write(''.join('%s: %s <br/>' % (a, getattr(o, a)) for a in dir(o)))
self.response.headers['Content-Type'] = "image/png"
self.response.out.write(o.blob)
And new question is :
if you upload a 'png' file, it will show successful, but when I upload a rar file I will run error. So how to set Content-Type automatically and what is the Content-Type of the 'rar' file?
Thanks
当我从 html 页面上传一个文件时,我可以成功上传,但是在下载时,我只能看到 __main__.MyModel object at 0x02506830
。我想知道如何才能自动设置 Content-Type,以便我能在下载时正确打开文件。
2、解决方案
要自动设置 Content-Type,有两种方法:
- 从 self.request.POST 而不是 self.request.get 获取文件
class upload(BaseRequestHandler):
def post(self):
file = self.request.POST['file']
# ...
这样,你就可以通过 file.type
来获取文件的 Content-Type。
- 使用
mimetypes.guess_type()
函数来猜测文件的 Content-Type
import mimetypes
class upload(BaseRequestHandler):
def post(self):
file = self.request.get('file')
# ...
content_type, encoding = mimetypes.guess_type(file.filename)
这样,你就可以通过 content_type
来获取文件的 Content-Type。
无论使用哪种方法,你都需要在下载时将 Content-Type 设置到响应头中。
class download(BaseRequestHandler):
def get(self):
# ...
self.response.headers['Content-Type'] = content_type
# ...
这样,当用户下载文件时,浏览器就能正确地打开它了。
对于第二个问题,rar 文件的 Content-Type 是 application/x-rar-compressed
。你可以在 IANA 网站 上找到更多关于 Content-Type 的信息。
以上示例展示了如何在 Java Spring Boot、Node.js (Express) 和 Python (Django) 中设置文件下载时的 Content-Type
。主要思路是根据文件路径或扩展名自动检测 MIME 类型,然后在响应头中添加 Content-Type
和 Content-Disposition
信息。