Django + Ajax | 文件上传 | 服务器无法识别Ajax请求

4 投票
3 回答
1979 浏览
提问于 2025-04-18 02:04

我正在尝试使用 ajax 和 Django 实现文件上传,但遇到了一些问题。

当用户选择文件并提交表单后,我认为应该通过 POST 方法向服务器发送一个 ajax 请求。但是在我的情况下,虽然确实向服务器发送了一个 POST 请求,但服务器却无法识别这是一个 ajax 请求,结果浏览器被重定向到了 http://<server>:<port>/upload/,这个页面的内容如下。

{"status": "error", "result": "Something went wrong.Try Again !!"}

Django 版本:1.6.2

Python 版本:2.7.5

同时,我是在 Django 开发服务器上进行测试。

views.py

def upload(request):
        logging.info('Inside upload view')
        response_data = {}
        if request.is_ajax():
                logging.info('Is_AJAX() returned True')
                form = UploaderForm(request.POST, request.FILES)

                if form.is_valid():
                        logging.info('Uploaded Data Validated')
                        upload = Upload( upload=request.FILES['upload'] )
                        upload.name = request.FILES['upload'].name
                        upload.save()
                        logging.info('Uploaded Data Saved in Database and link is %s' % upload.upload)

                        response_data['status'] = "success"
                        response_data['result'] = "Your file has been uploaded !!"
                        response_data['fileLink'] = "/%s" % upload.upload

                        return HttpResponse(json.dumps(response_data), content_type="application/json")

        response_data['status'] = "error"
        response_data['result'] = "Something went wrong.Try Again !!"

        return HttpResponse(json.dumps(response_data), content_type='application/json')

模板

<form id="uploadForm" action="/upload/" method="post" enctype="multipart/form-data">
                {% csrf_token %}
<input id="fileInput" class="input-file" name="upload" type="file">
<input type="submit" value="Post Images/Files" />
</form>

JavaScript 1:

$('#uploadForm').submit(function(){

        var formData = new FormData($(this)[0]);
        $.ajax({
                url: '/upload/',
                type: 'POST',
                data: formData,
                async: false,
                success: function (data) {
                alert(data)
                },
                cache: false,
                contentType: false,
                processData: false
        });
        return false;
});

JavaScript 2

var options = {
      url: '/upload/',
      type: "POST",
       error: function(response) {
               alert('Something went Wrong. Try Again');
        },
        success: function(response) {
            if ( response.status == 'success' ) {
              alert('success');
             }
        }
};

$('#uploadForm').ajaxSubmit(options);

问题:

1) 为什么 Django 无法识别 ajax 请求,request.is_ajax() 的值总是 False

2) 即使服务器不识别 ajax 请求,为什么我的浏览器会被重定向到另一个页面?

这里还有一个类似的问题 在这里,但没有得到解决。

3 个回答

-1

1) 为什么 is_ajax() 不工作?
你有没有包含 JQuery 表单插件 (jquery.form.js)?因为 ajaxSubmit() 需要这个插件。

你可以看看这个链接:http://jquery.malsup.com/form/

如果已经包含了插件,你可以检查一下 HTTPRequest 对象。

Django 的文档说 HttpRequest.is_ajax() 会返回 True,如果请求是通过 XMLHttpRequest 发出的。如果你使用一些 JavaScript 库来发送 ajax 请求,那就不用担心这个问题。不过,你可以检查一下 "HTTP_X_REQUESTED_WITH" 这个头信息,看看 Django 是否收到了 XMLHttpRequest

2) 为什么页面会重定向?

正如我上面提到的,处理 ajax 请求和回调需要用到 JQuery 表单插件。此外,对于 ajaxSubmit(),你需要重写 $(#uploadForm).submit()

 $('#uploadForm').submit( function (){
     $(this).ajaxSubmit(options);
 return false;
 });

希望这些对你有帮助 :)

4

这个对我有效。你需要一个 jquery.form.js 文件。

$("#uploadForm").submit(function(event) {
    $(this).ajaxSubmit({
        url:'{% url upload_file %}',
        type: 'post',
        success: function(data) {
            console.log(data)
        },
        error: function(jqXHR, exception) {
            console.log("An error occurred while uploading your file!");
        }
    });
    return false;
});

这里有一个类似的问题,答案可以在 这里 找到。

2

确保你的javascript代码块

$('#uploadForm').submit(function(){

    var formData = new FormData($(this)[0]);
    $.ajax({
            url: '/upload/',
            type: 'POST',
            data: formData,
            async: false,
            success: function (data) {
            alert(data)
            },
            cache: false,
            contentType: false,
            processData: false
    });
    return false;
});

是在页面上你的uploadForm这个表单加载之后再执行的。在你的情况下,看起来你试图把提交处理程序绑定到还没有加载的表单元素上,所以当你点击时,它只是发送了一个简单的POST请求。

撰写回答