【问题标题】:HTML, jQuery, Python - Form File Upload (GAE)HTML、jQuery、Python - 表单文件上传 (GAE)
【发布时间】:2015-09-01 19:21:02
【问题描述】:

我查看了很多问题,但似乎找不到解决我的具体问题的问题。

我正在尝试允许用户(在我的 Google App Engine 网站上)将视频上传到 wistia(视频主机)。

我可以通过直接打开文件来让它工作,但这只有在文件已经在 app 文件夹中时才有效:

class VideoUploadHandler(webapp2.RequestHandler):
    def post(self):
        title = self.request.get('title')
        video = self.request.get('video')
        description = self.request.get('description')

        url = 'https://upload.wistia.com'
        params = {
            'api_password'    : 'my_password',
            'file'            : open(video, "rb"),  #<--- HOW TO USE FILE OBJECT?
            'project_id'      : 'my_project_id',
            'name'            : title,
            'description'     : description,
            }
        opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler) 
        response = opener.open(url, params)

        logging.warning(response.read())

        self.redirect("https://www.my_webpage.com/")

如果变量 'video' 仅仅是文件名并且文件位于同一个文件夹中,则此方法有效,但我显然需要允许用户选择任何文件,所以我将我的 HTML 更改为:

HTML:

<form enctype="multipart/form-data" action="/video_upload/" method="post">
<p>Title: <input type="text" name="title"/></p>
<p><input type="file" name="video"/></p>
<p>Description:<br><textarea rows="4" cols="50" name="description"></textarea></p>
<p><input type="submit" value="Upload"/></p>
</form>

但是,我无法理解如何在我的 POST 请求中使用文件对象。出于某种原因,我无法从已发布的其他答案中收集到这些信息。

如何使用这种 HTML 表单方法构建我的“参数”?



编辑:

为了澄清,我现在有了这个简单的 HTML:

<input id="video_input" type="file" name="video"/>
<a id="video_button">SUBMIT VIDEO</a>

这个基于thisthis的JavaScript:

$('#video_button').click(function() {
    var file = new FormData();
    file.append('video', $('#video_input').get(0).files[0]);
    $.ajax({
        type: "POST",
        url: "/video_upload/",
        data: file,
        processData: false,
        contentType: false
    });
});

但我仍然没有找到任何充分解释如何获取我现在在 Python 中拥有的文件对象并将其正确传递给 wistia POST 参数的任何内容。有什么想法或链接吗?




编辑: 使用时的回溯:

params = {
            'api_password'    : 'my_password',
            'file'            : video,
            'project_id'      : 'my_project_id',
            'name'            : title,
            'description'     : description,
            }

(video.py) 是带有 VideoUploadHandler 类的文件。

WARNING  2015-09-05 07:13:16,970 urlfetch_stub.py:504] Stripped prohibited headers from URLFetch request: ['Content-Length', 'Host']
ERROR    2015-09-05 12:13:21,026 webapp2.py:1552] HTTP Error 500: Internal Server Error

Traceback (most recent call last):

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1535, in __call__

    rv = self.handle_exception(request, response, e)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1529, in __call__

    rv = self.router.dispatch(request, response)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher

    return route.handler_adapter(request, response)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 1102, in __call__

    return handler.dispatch()

  File "C:\...\webapp2-2.5.2\webapp2.py", line 572, in dispatch

    return self.handle_exception(e, self.app.debug)

  File "C:\...\webapp2-2.5.2\webapp2.py", line 570, in dispatch

    return method(*args, **kwargs)

  File "C:\...\video.py", line 84, in post

    response = opener.open(url, params)

  File "C:\...\urllib2.py", line 410, in open

    response = meth(req, response)

  File "C:\...\urllib2.py", line 523, in http_response

    'http', request, response, code, msg, hdrs)

  File "C:\...\urllib2.py", line 448, in error

    return self._call_chain(*args)

  File "C:\...\urllib2.py", line 382, in _call_chain

    result = func(*args)

  File "C:\...\urllib2.py", line 531, in http_error_default

    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)

HTTPError: HTTP Error 500: Internal Server Error

INFO     2015-09-05 07:13:21,700 module.py:788] default: "POST /video_upload/ HTTP/1.1" 500 2253

【问题讨论】:

    标签: jquery python file google-app-engine post


    【解决方案1】:

    编辑:试试这个:

    from poster.encode import multipart_encode, MultipartParam
    from google.appengine.api import urlfetch
    
    class VideoUploadHandler(webapp2.RequestHandler):
        def post(self):
            title = self.request.get('title')
            description = self.request.get('description')
            payload = {
                'api_password'    : 'my_password',
                'project_id'      : 'my_project_id',
                'name'            : title,
                'description'     : description,
                }
            file_data = self.request.POST['video']
            payload['file'] = MultipartParam('file', filename=file_data.filename,
                                                  filetype=file_data.type,
                                                  fileobj=file_data.file)
            data,headers= multipart_encode(payload)
            send_url = "https://upload.wistia.com"
            resp = urlfetch.fetch(url=send_url, payload="".join(data), method=urlfetch.POST, headers=headers)       
            logging.info(resp)
            self.redirect("/")
    

    你需要这个lib,这是改编自这个post

    【讨论】:

    • 感谢瑞恩的评论!我实际上已经尝试过了,但是我遇到了一个错误,所以我用文本文件再次尝试了。当我记录“视频”变量(这次是文本文件)时,它确实显示了纯文本。于是,我又试了一遍视频。当我记录'video'变量(在python脚本中)实际上是一个视频时,我得到类似:“%%5£µÇùËmÂ{oWWü¼(‘Ü# ’ÓàåžuGU¥ˆû”(但是更久,更长)。但是,我从服务器收到 500 错误。我会将回溯添加到我原来的问题中。
    • 奇怪的是,当我这样做时:" 'file' : open(video_name_in_current_folder, "rb"), " 它有效 - 我的视频上传到 wistia 没有问题.
    • 看起来它与 MultipartPostHandler.MultipartPostHandler 处理文件的方式有关。打开它正在发送文件句柄,而“视频”是原始文件。这就解释了为什么一个有效而另一个无效。这似乎是 MultipartPostHandler 处理程序的限制。我将把上面的代码编辑成我开始工作的代码。
    • 效果比我预期的还要好。它不仅有效,而且似乎比其他选项更顺利地处理上传。谢谢!
    猜你喜欢
    • 2013-08-14
    • 2016-05-01
    • 2010-12-05
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多