Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何防止ajax post请求提交两次?_Javascript_Jquery_Ajax_Laravel - Fatal编程技术网

Javascript 如何防止ajax post请求提交两次?

Javascript 如何防止ajax post请求提交两次?,javascript,jquery,ajax,laravel,Javascript,Jquery,Ajax,Laravel,我有一个按钮subscribe,它应该通过ajax向我的控制器提交post请求,以便插入到我的表中 这就是我的观点: @extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8"> <div c

我有一个按钮subscribe,它应该通过ajax向我的控制器提交post请求,以便插入到我的表中

这就是我的观点:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8">
            <div class="flash-message"></div>
            <div class="card">
                <div class="card-header">
                    <div class="level">
                        <span class="flex"><a href="{{route('profile',$thread->creator->name)}}">{{$thread->creator->name}}</a> posted:
                            {{$thread->title}}
                        </span>
                        @if(auth()->check())
                        @if($subscription)
                        <button class="btn btn-secondary" id="unsubscribe">Unsubscribe</button>
                        @else
                        <button class="btn btn-danger" id="subscribe">Subscribe</button>
                        @endif
                        @endif
                        @can('update',$thread)
                        <a href="{{$thread->path()}}/edit" class="btn btn-link">Edit Thread</a>
                        <form action="{{$thread->path()}}" method="POST">
                            @csrf
                            @method('delete')
                            <button class="btn btn-link" type="submit">Delete Thread</button>
                        </form>
                        @endcan
                    </div>
                </div>
                <div class="card-body">
                {{$thread->body}}
                </div>
            </div>

..............
@extends('layouts.app'))
@节(“内容”)
张贴:
{{$thread->title}
@如果(auth()->check())
@if(订阅费)
退订
@否则
订阅
@恩迪夫
@恩迪夫
@can('update',$thread)
@csrf
@方法('delete')
删除线程
@恩德坎
{{$thread->body}
..............
我的应用程序刀片:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!--jQuery/share.js -->
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script>
    <script src="{{ asset('js/share.js') }}"></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    <style>
        body{
            padding-bottom:100px;
        }
        .level{
            display: flex;
            align-items: center;
        }
        .flex{
            flex: 1;
        }
    </style>
</head>
<body>
      <div id="app">
        @include('layouts.nav')
        <main class="py-4">
            @yield('content')
        </main>
    <flash message="{{session('flash')}}"></flash>
    </div>
</body>

<style>
    .btn-width{
        min-width: 70px;
      }
</style>


</html>


{{config('app.name','Laravel')}
身体{
填充底部:100px;
}
.级别{
显示器:flex;
对齐项目:居中;
}
.flex{
弹性:1;
}
@包括('layouts.nav')
@产量(‘含量’)
.btn宽度{
最小宽度:70px;
}
调用按钮的代码:

<script type="application/javascript">

    $(document).ready(function(){
        $('#subscribe').click(function(e){
            e.preventDefault();
            $.ajaxSetup({
                  headers: {
                      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                  }
              });
              
            $.ajax({
                url: "{{route('subscription.store')}}",
                method:'POST',
                data: {
                    thread_id: "{{$thread->id}}",
                },
                success:function(response){
                    $('div.flash-message').html(response);
                   
                },
                error:function(error){
                    console.log(error);
                }
            });
        });
    });

$(文档).ready(函数(){
$(“#订阅”)。单击(函数(e){
e、 预防默认值();
$.ajaxSetup({
标题:{
'X-CSRF-TOKEN':$('meta[name=“CSRF-TOKEN”]).attr('content'))
}
});
$.ajax({
url:“{route('subscription.store')}}”,
方法:'POST',
数据:{
线程id:“{{$thread->id}}”,
},
成功:功能(响应){
$('div.flash-message').html(响应);
},
错误:函数(错误){
console.log(错误);
}
});
});
});
据我所知,没有其他元素与我的按钮共享相同的id。而且,我的按钮不是表单提交,所以不应该调用两次。检查开发工具不会显示任何错误,在“网络”选项卡中,使用同一启动器相同地调用两个请求。 所以,我有点想知道为什么会发生这种情况。ajax post请求不应该只提交一次请求吗

我真的很想弄清这一点,因为大多数其他类似的问题都会调用submit两次,而我的代码应该只调用它一次。相反,它对我的数据库进行了两次插入


我还可以做些什么来找出问题的根本原因?

您正在调用函数两次,一次在document ready中,另一次在按钮上单击remover document您是否尝试过返回false?像这样:

$(document).ready(function(){
    let subscribeClick = function() {
     $.ajaxSetup({
              headers: {
                  'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
              }
          });
          
        $.ajax({
            url: "{{route('subscription.store')}}",
            method:'POST',
            data: {
                thread_id: "{{$thread->id}}",
            },
            success:function(response){
                $('div.flash-message').html(response);
               
            },
            error:function(error){
                console.log(error);
            }
        });
        return false;
    }
    $('#subscribe').click(function(e){
        e.preventDefault();
        e.stopImmediatePropagation();
        subscribeClick(); 
    });
});

您的javascript是否可能被加载了两次?这将附加两个相同的侦听器,并在一次单击中发送两次请求。如果在事件处理程序中放置一个console.log,是否也会看到两次

另外,显然,
。单击
会为与传递给jQuery对象的选择器相匹配的每个元素添加一个单独的事件侦听器。如果你这样做会发生什么

$(文档).ready(函数(){
$(“#订阅”)。在(“单击”上,函数(e){
e、 预防默认值();
$.ajaxSetup({
标题:{
“X-CSRF-TOKEN”:$('meta[name=“CSRF TOKEN”]”)attr(“内容”),
},
});
$.ajax({
url:“{route('subscription.store')}}”,
方法:“张贴”,
数据:{
线程id:“{{$thread->id}}”,
},
成功:功能(响应){
$(“div.flash-message”).html(响应);
},
错误:函数(错误){
console.log(错误);
},
});
});
});

您可以尝试以下选项:

(1) 在ajax调用中使用
async:false
,停止其他代码的执行,直到收到当前ajax调用的响应为止

 $('#subscribe').click(function(e) {
    e.preventDefault();
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    $.ajax({
        url: "{{route('subscription.store')}}",
        method: 'POST',
        async: false,
        data: {
            thread_id: "{{$thread->id}}",
        },
        success: function(response) {
            $('div.flash-message').html(response);

        },
        error: function(error) {
            console.log(error);
        }
    });
});

(2) 您可以使用事件接口的
stopPropagation()
方法来防止当前事件在捕获和冒泡阶段进一步传播

$('#subscribe').click(function(e) {
    e.preventDefault();
    e.stopPropagation();
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    $.ajax({
        url: "{{route('subscription.store')}}",
        method: 'POST',
        async: false,
        data: {
            thread_id: "{{$thread->id}}",
        },
        success: function(response) {
            $('div.flash-message').html(response);

        },
        error: function(error) {
            console.log(error);
        }
    });
});

(3) 使用存储请求状态的变量

var isLoading = false;
$(document).ready(function() {
    $('#subscribe').click(function(e) {
        if (!isLoading ) { 
            isLoading = true; //make true when request starts
            e.preventDefault();
            $.ajaxSetup({
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                }
            });

            $.ajax({
                url: "{{route('subscription.store')}}",
                method: 'POST',
                data: {
                    thread_id: "{{$thread->id}}",
                },
                success: function(response) {
                    $('div.flash-message').html(response);
                    isLoading = false; //make false when response is received
                },
                error: function(error) {
                    console.log(error);
                    isLoading = false; //make false when error is received
                }
            });
        }
    });
});

如果我在事件preventDefault之后添加stopImmediatePropagation,那么它就可以工作了。但是,我只是想了解问题的原因,因为它在默认情况下应该工作。-preventDefault:如果事件可取消,则取消事件,而不停止事件的进一步传播。-停止传播:阻止当前事件的进一步传播。-stopImmediatePropagation:防止调用同一事件的其他侦听器。您知道为什么会发生这种情况吗?我使用了很多POST ajax请求,从来没有使用过stopPropagation。我不太理解你的情况,但也许这个链接会让你更好地理解我的意思是说我通过ajax的POST请求应该正常工作,但在我的情况下,它不工作,并试图找出原因。你使用的是什么版本的jQuery?也许只是试着让按钮保持单独,看看它是否发生了?评论不用于扩展讨论;这段对话已经结束。