You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止地理定位重复提交?犯罪预警网站提交异常排查

解决犯罪预警网站重复提交(含/不含经纬度双记录)问题

当前开发的犯罪预警网站存在重复提交问题——用户点击提交后,会生成两条预警记录:一条带有效经纬度,一条经纬度为None。

预期输出(单条有效记录)

lucas posted a crime alert!
Alert!!! cv !!!

Crime reported from Ogbia, Bayelsa

Crime coordinates: Longitude 3.325952 | Latitude 6.599475

Category: c

March 9, 2023, 1:53 p.m.

实际输出(重复双记录)

lucas posted a crime alert!
Alert!!! cv !!!

Crime reported from Ogbia, Bayelsa

Crime coordinates: Longitude 3.325952 | Latitude 6.599475

Category: c

March 9, 2023, 1:53 p.m.

lucas posted a crime alert!
Alert!!! cv !!!

Crime reported from Ogbia, Bayelsa

Crime coordinates: Longitude None | Latitude None

Category: c

March 9, 2023, 1:53 p.m.

现有代码

Django Views 代码

def new_alert(request):
    if request.method == "POST":
        content = request.POST.get("content")
        state = request.POST.get("state")
        lga = request.POST.get("lga")
        category = request.POST.get("category")
        current_user = request.user
        lat = request.POST.get("lat")
        lng = request.POST.get("lng")
        # Create a new alert
        new_alert = Alert(content=content, state=state, lga=lga, user=current_user, category=category, latitude=lat, longitude=lng)
        new_alert.save()
        return HttpResponseRedirect(reverse("all_alerts"))
    else:
        return render(request, "new_alert.html")

JavaScript 代码

<script>
  function getLocation() {
    if (navigator.geolocation) {
      // Display confirmation prompt
      if (confirm("Allow this website to access your location?")) {
        navigator.geolocation.getCurrentPosition(sendLocation);
      } else {
        alert("Location access denied.");
      }
    } else {
      alert("Geolocation is not supported by this browser.");
    }
  }

  function sendLocation(position) {
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;

    console.log("Sending data: ", { lat: lat, lng: lng });

    // Get the CSRF token from the form
    var csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;

    // Get the form data using FormData
    var form_data = new FormData(document.querySelector('#form-id'));

    // Add the lat and lng values to the form data
    form_data.append('lat', lat);
    form_data.append('lng', lng);

    // Send the AJAX request with the form data
    $.ajax({
      url: 'new_alert',
      type: 'POST',
      data: form_data,
      contentType: false,
      processData: false,
      beforeSend: function (xhr) {
        xhr.setRequestHeader('X-CSRFToken', csrftoken);
      },
      error: function (xhr, status, error) {
        alert('Fill the fields before submitting Alert');
      }
    });
  }
</script>

HTML 代码(移除下拉选项后)

<form id="form-id" action="{% url 'new_alert' %}" method="POST">
    {% csrf_token %}
    <div class="form-group">
        <textarea id="create-post-text" name="content" placeholder="Report crime" required></textarea>
    </div>
    <div class="form-group">
        <label class="control-label">Where Are You Reporting From?</label>
      
    </div>

    <div class="form-group">
        <label class="control-label">LGA of Origin</label>
        <select name="lga" id="lga" class="form-control select-lga" required>
        </select>
    </div>
    <div class="form-group">
        <input class="form-control" name="category" placeholder="Specify a category. For example, murder, theft, vandalism, etc" required>
    </div>

    <button onclick="getLocation()" class="btn btn-success" id="sendLocation">Alert!</button>

</form>

问题根源

按钮默认是submit类型,点击时同时触发两个动作:

  1. 执行onclick中的getLocation(),通过AJAX提交带经纬度的表单数据;
  2. 触发表单默认提交行为,直接提交无经纬度的原始表单,生成None记录。

解决步骤

1. 阻止按钮的默认表单提交行为

推荐直接修改按钮类型为button,避免默认提交:

<button type="button" onclick="getLocation()" class="btn btn-success" id="sendLocation">Alert!</button>

也可以在onclick中返回false阻止默认行为:

<button onclick="getLocation(); return false;" class="btn btn-success" id="sendLocation">Alert!</button>

2. 优化AJAX提交后的页面跳转

AJAX请求不会自动触发Views中的重定向,需在回调中手动跳转:

$.ajax({
  url: 'new_alert',
  type: 'POST',
  data: form_data,
  contentType: false,
  processData: false,
  beforeSend: function (xhr) {
    xhr.setRequestHeader('X-CSRFToken', csrftoken);
  },
  success: function() {
    // 提交成功后跳转到预警列表页
    window.location.href = "{% url 'all_alerts' %}";
  },
  error: function (xhr, status, error) {
    alert('Fill the fields before submitting Alert');
  }
});

3. 可选:处理用户拒绝定位的情况

如果需要允许用户拒绝定位后仍提交预警,可修改getLocation函数:

function getLocation() {
  if (navigator.geolocation) {
    if (confirm("Allow this website to access your location?")) {
      navigator.geolocation.getCurrentPosition(sendLocation);
    } else {
      alert("Location access denied. You can still submit the alert without location data.");
      // 手动提交无经纬度的表单
      document.querySelector('#form-id').submit();
    }
  } else {
    alert("Geolocation is not supported by this browser.");
    document.querySelector('#form-id').submit();
  }
}

内容的提问来源于stack exchange,提问作者Lukman Samson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:52:06