在 web.py 中使用 xheditor 上传接口开发上传功能笔记

这个问题让我彻夜难眠,誓死要解决它。我会把我的纠结写在下面,作为笔记,希望能帮助到那些纠结 web.py 的朋友。

关于 web.py 如何上传文件,直接看官方文档:http://webpy.org/cookbook/storeupload.zh-cn

xheditor 的上传支持 HTML4 和 HTML5 的方式上传。根据抓包,知道 HTML5 上传方式是将 HTTP_CONTENT_DISPOSITION 写到 HTTP 请求头部,POST 的内容就是整个文件的内容;HTML4 上传是把 HTTP_CONTENT_DISPOSITION 内容放在 POST 数据里的。于是,web.py 是这样接受数据的:

upFile = web.input(filedata={})

你会发现如果用 xheditor 上传 API 的话,会500错误,看 Apache 的日志又会发现 upFile 变量引用不存在的键引发的 KeyError 异常。

这个问题就很明显了,firebug 抓包,会发现是用的 HTML5 方式上传文件。于是,我跟踪 web.py 的源码,关于接受 GET、POST、PUT 的请求在 webapi.py 的 278~313 行是实现(web.py 直接用标准库中的 cgi 处理的),发现 web.py 不能处理 HTML5 的上传方式。

那么就只有用 HTML4 上传了,因为 xheditor 官方说支持 HTML4 和 HTML5 方式上传,于是我满谷歌满百度地搜索啊,都没发现如何单独调用 HTML4 方式上传。果断就看 xheditor.js 的源码,在 1682~1708 行找到了原因,原来 xheditor 先检查是否支持 HTML5 上传:

if(isOpera||!bHtml5Upload||(fromFiles.nodeType&&!((fileList=fromFiles.files)&&fileList[0].name)))

如果支持,则用 HTML5 上传,否则用 HTML4 方式上传。

纠结就这么来了,web.py 只能用 HTML4 方式上传,而 xheaditor 默认又是用 HTML5 方式上传。只有修改 xheditor.js 的代码了,把 this.startUpload 跟 HTML5 上传有关的判断之类的该删除的都删除了。最后,终于成功了。

最后,因为 xheaditor 上传后返回的结果需要是 JSON 格式的,在 Python 里,直接 import json,然后 return json.dumps({'err':'','msg':filename}) 就可以了。