在 iOS 设备上发出 POST 请求后保持相同的网页(Django 发送 204 状态响应)

我的 Django 项目在网页上有许多按钮,它们向主程序发送 POST 请求,主程序view.py依次处理操作并返回204 No content响应。操作的结果稍后会异步显示在网页上(生成响应时,没有任何新内容可显示)。在任何基于非 iOS 的浏览器上,204 响应都可以正常工作,并且网页保留在浏览器中,正如RFC 7231所期望的那样。不幸的是,我尝试过的所有基于 iOS 的浏览器(Safari、Firefox、Chrome)都会在 POST 后导航到空白页面,这不是我想要的(请参阅此问题)。显然这是WebKit 中长期存在的错误

有什么方法可以在所有浏览器上实现相同的效果吗?IE。单击按钮,POST,网页保持原样,更改稍后出现。我看过这个,但不确定这真的是我想要的。更改响应代码是可能的,但我没有看到不离开当前页面的可行替代方案。我目前的黑客修复是为 iOS 设备重新加载整个页面,但是如果用户之前向下滚动,这会移动页面,所以看起来很卡顿。


慕婉清6462132
浏览 78回答 1
1回答

qq_花开花谢_0

event.preventDefault() 简短的答案是在您自己的函数中为每个表单覆盖常规表单提交onsubmit。然后使用 JQuery 异步执行 POST。这避免了服务器必须返回状态为 204 的 HttpResponse,或者除了空的 JsonResponse 之外的任何其他内容。我的网页上有多个表单,因此我没有为每个按钮分配单个功能,如上面链接的答案中所示,但有几个可以更改单个按钮的行为。另外,对于 Django,还需要考虑在 POST 请求中包含 CSRF 令牌。例如,一些带有两个按钮的 html;<form id="form-a" onsubmit="submit_form_a(event)">{% csrf_token %}    <input type="hidden" name="button-a" value="some_value_for_a">    <button type="submit" class="w3-button">Button A</button></form><form id="form-z" onsubmit="submit_form_z(event)">{% csrf_token %}    <input type="hidden" name="button-z" value="some_value_for_z">    <button type="submit" class="w3-button">Button Z</button></form>然后是 Javascript,例如,第一个表单提交回调禁用按钮;function submit_form_a(e){    e.preventDefault();    var url = "/main/a"    var formData = $(e.target).serialize();    var btn = $(e.target).find("button");    btn.prop("disabled", true);    myPost(url, formData);}第二个提交回调使用优秀的W3.CSS执行一些动画;function submit_form_z(e){   e.preventDefault();   var url = "/main/z"   var formData = $(e.target).serialize();   var btn = $(e.target).find("button");   btn.toggleClass("w3-animate-fading").toggleClass("w3-text-red")   myPost(url, formData);}这两个脚本都调用一个通用脚本mypost,该脚本使用 CSRF 令牌设置 XMLHttpResponse 标头,然后将其发布;// Make sure any AJAX POST requests are not going off-site. Prevents// leaking the CSRF token.function csrfSafeMethod(method) {// these HTTP methods do not require CSRF protection    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } function myPost(url, data) {    var csrftoken = $("[name=csrfmiddlewaretoken]").val();    // Set the header on the AJAX POST request with the CSRF token    $.ajaxSetup({beforeSend: function(xhr, settings) {        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {            xhr.setRequestHeader("X-CSRFToken", csrftoken);        }    }});    $.post(url, data);}回到 Djangoviews.py方面,查看<input>表单中的数据并执行您需要执行的操作。我刚刚发现 iOS 上的按钮本身并不包含在 POST 表单数据中,就像其他平台上的那样,因此需要隐藏的文本输入元素;if request.is_ajax() and request.method == 'POST':    if 'button-a' in request.POST:        # do something for A    elif 'button-z' in request.POST:      # do something for Z    return JsonResponse({})瞧!可以单击按钮,发生背景操作,并且页面不会移动。您可以返回除空 JSON 响应之外的其他内容,并在表单回调中处理它,例如重新启用按钮,但我不需要这样做。有关详细信息,请参阅之前链接的答案。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Html5