ホームページ > バックエンド開発 > PHPチュートリアル > 文本表单和图片一起进行ajax提交,表单是值,图片是对象,发送时有些问题

文本表单和图片一起进行ajax提交,表单是值,图片是对象,发送时有些问题

WBOY
リリース: 2016-06-06 20:18:42
オリジナル
1381 人が閲覧しました

代码如下:

<code>


    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/tether/1.1.1/css/tether.min.css" rel="stylesheet">




<div class="container">
    <fieldset class="form-group">
        <label for="title">标题</label>
        <input type="text" class="form-control" id="title" placeholder="">
    </fieldset>
    <fieldset class="form-group">
        <label for="content">内容</label>
        <textarea class="form-control" id="content" rows="3"></textarea>
    </fieldset>
    <fieldset class="form-group">
        <label for="photo">图片</label>
        <input type="file" name="file" accept="image/*" class="form-control-file" id="photo">
        <img  id="preview" alt="文本表单和图片一起进行ajax提交,表单是值,图片是对象,发送时有些问题" >
    </fieldset>
    <a id="submit" class="btn btn-primary">submit</a>
</div>

<script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/tether/1.1.1/js/tether.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/js/bootstrap.min.js"></script>

// 用到了localResizeIMG插件,压缩图片: https://github.com/think2011/localResizeIMG
<script src="js/dist/lrz.all.bundle.js"></script>
<script>
    $(function () {
        var $preview = $('#preview');
        var formData = null;

        //压缩图片
        $('#photo').on('change', function () {
            lrz(this.files[0], {
                width: 800
            }).then(function (rst) {
                //图片预览
                $preview.attr('src', rst.base64);

                //根据需要增加一些信息
                rst.formData.append('fileLen', rst.fileLen);

                //压缩后的图片暂存在变量formData中
                formData = rst.formData;
            });
        });

        //ajax请求
        $("#submit").click(function () {
            //设置TOKEN
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $.ajax({
                type: "POST",
                url: "{{ url('article/') }}",
                dataType: 'json',
                processData: false,
                contentType: false,  
                cache: false,
                data: {
                    title: $("#title").val(),
                    content: $("#content").val(),
                    photo: formData
                }
            }).done(function (data) {
                alert(JSON.stringify(data));
            }).fail(function (jqXHR, textStatus) {
                console.log(jqXHR);
                console.log(textStatus);
            });
        });
    });
</script>


</code>
ログイン後にコピー
ログイン後にコピー

示例中,有两个文本表单,另外还有一张图片,一起提交到后台,
因为普通提交不能压缩图片,所以用js在前端压缩后,用ajax一起提交到后台,
提交过程中问题如下:
主要跟这两项相关:

<code>processData: false,
contentType: false,</code>
ログイン後にコピー
ログイン後にコピー

1、如果让这两项生效,Request payload显示为:[object Object],ajax请求能成功发送,但jquery拿不到表单的值。

2、如果注释掉这两项,谷歌浏览器控制台报错:Uncaught TypeError: Illegal invocation,ajax请求不能发送。

不知怎么弄

回复内容:

代码如下:

<code>


    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.bootcss.com/tether/1.1.1/css/tether.min.css" rel="stylesheet">




<div class="container">
    <fieldset class="form-group">
        <label for="title">标题</label>
        <input type="text" class="form-control" id="title" placeholder="">
    </fieldset>
    <fieldset class="form-group">
        <label for="content">内容</label>
        <textarea class="form-control" id="content" rows="3"></textarea>
    </fieldset>
    <fieldset class="form-group">
        <label for="photo">图片</label>
        <input type="file" name="file" accept="image/*" class="form-control-file" id="photo">
        <img  id="preview" alt="文本表单和图片一起进行ajax提交,表单是值,图片是对象,发送时有些问题" >
    </fieldset>
    <a id="submit" class="btn btn-primary">submit</a>
</div>

<script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/tether/1.1.1/js/tether.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.2/js/bootstrap.min.js"></script>

// 用到了localResizeIMG插件,压缩图片: https://github.com/think2011/localResizeIMG
<script src="js/dist/lrz.all.bundle.js"></script>
<script>
    $(function () {
        var $preview = $('#preview');
        var formData = null;

        //压缩图片
        $('#photo').on('change', function () {
            lrz(this.files[0], {
                width: 800
            }).then(function (rst) {
                //图片预览
                $preview.attr('src', rst.base64);

                //根据需要增加一些信息
                rst.formData.append('fileLen', rst.fileLen);

                //压缩后的图片暂存在变量formData中
                formData = rst.formData;
            });
        });

        //ajax请求
        $("#submit").click(function () {
            //设置TOKEN
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $.ajax({
                type: "POST",
                url: "{{ url('article/') }}",
                dataType: 'json',
                processData: false,
                contentType: false,  
                cache: false,
                data: {
                    title: $("#title").val(),
                    content: $("#content").val(),
                    photo: formData
                }
            }).done(function (data) {
                alert(JSON.stringify(data));
            }).fail(function (jqXHR, textStatus) {
                console.log(jqXHR);
                console.log(textStatus);
            });
        });
    });
</script>


</code>
ログイン後にコピー
ログイン後にコピー

示例中,有两个文本表单,另外还有一张图片,一起提交到后台,
因为普通提交不能压缩图片,所以用js在前端压缩后,用ajax一起提交到后台,
提交过程中问题如下:
主要跟这两项相关:

<code>processData: false,
contentType: false,</code>
ログイン後にコピー
ログイン後にコピー

1、如果让这两项生效,Request payload显示为:[object Object],ajax请求能成功发送,但jquery拿不到表单的值。

2、如果注释掉这两项,谷歌浏览器控制台报错:Uncaught TypeError: Illegal invocation,ajax请求不能发送。

不知怎么弄

看了以下,这个插件是利用了FormData对象来发送文件的,所以你用jQuery.ajax()发送的数据的data属性必须是FormData对象,不能把FormData对象再作为data属性的子属性。

<code>$.ajax({
    type: "POST",
    url: "{{ url('article/') }}",
    dataType: 'json',
    processData: false,
    contentType: false,  
    cache: false,
    data: {
        title: $("#title").val(),
        content: $("#content").val(),
        photo: formData    //这里错了,不能把FormData对象作为data属性的子属性
    }
})
</code>
ログイン後にコピー

应该是这样才对:

<code>$.ajax({
    type: "POST",
    url: "{{ url('article/') }}",
    dataType: 'json',
    processData: false,
    contentType: false,  
    cache: false,
    data: formData    //直接把formData对象作为data属性的值发送
})
</code>
ログイン後にコピー

如果你要附加字段,可以用FormData对象的append方法:

<code>//这段代码要在ajax请求之前
formData.append('title', $("#title").val());
formData.append('content',$("#content").val());
</code>
ログイン後にコピー

如果你要想把图片文件的字段名设置成photo,在localResizeIMG参数文档力其实已经说明了,就是在你压缩图片的代码那里这样修改:

<code>lrz(this.files[0], {
    width: 800,
    fieldName: 'photo'    //把上传图片文件的字段设置为photo
})
</code>
ログイン後にコピー

另外要注意,FormData对象在IE上只有版本10以上才支持,其他现代浏览器(Firefox、Chrome、Safari、MS Edge等)都没问题。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート