2016-07-09 17 views
0

私のFlask-appでは、ユーザーがリンクをクリックしたときにAJAX呼び出しによるPOST要求を実装しようとしています。 これはChromiumの魅力のように機能します。 httpieのいずれかを通して私のビュー機能を要求するとき、私は何の問題もありません:AJAXによるPOSTリクエストはFirefoxでエラー404しか発生しません

$ http --json POST http://127.0.0.1:5000/ctrl/remove-category id=1 csrf=1 

(venv) $ : http --json POST http://127.0.0.1:5000/ctrl/remove-category id=5 csrf=1 
HTTP/1.0 200 OK 
Content-Length: 78 
Content-Type: application/json 
Date: Sat, 09 Jul 2016 09:05:20 GMT 
Server: Werkzeug/0.11.8 Python/3.5.1 

{ 
    "message": "Category 'test 5' has been removed", 
    "status": "success" 
} 

をしかし、奇妙なFirefoxで何かが起こります。私は2つのFFプロファイルの下でそれをテストしました。どちらも404エラーです。私の最初のFFプロフィールの下にあるリンクをクリックすると404が表示され、何も起こりません。つまり、WerkzeugサーバーにPOST要求が表示されず、GET要求のみ表示されます。私はまだFirebugのコンソールでエラーを取得する第二FFプロファイルの下で

POST http://127.0.0.1:5000/ctrl/remove-category 31ms  jquery.min.js (line 6) 
Error code: 404            categories (line 455) 

だから、POSTリクエストが送信され、私は私のWERKZEUGログにそれを見ている:

127.0.0.1 - - [09/Jul/2016 11:29:11] "POST /ctrl/remove-category HTTP/1.1" 200 - 
127.0.0.1 - - [09/Jul/2016 11:29:12] "GET /ctrl/categories HTTP/1.1" 200 - 

それでも、私はまだ私のAJAX `.success 'コールで他のことをやってはいけません。(ローカルストレージなどに保存するなど)

ここに私のjQueryスクリプトです:

私はjQueryの2.0.3、フラスコ0.10.1、フラスコ-WTF 0.9.4とFirefox 47.0を使用してい

@csrf.exempt # for httpie testing 
@ctrl.route('/remove-category', methods=['POST']) 
#@permission_required(Permission.ADMINISTER) # httpie testing 
def remove_category(): 
    try: 
     id = request.json['id'] 
     csrf = request.json['csrf'] 
    except KeyError: 
     return jsonify({ 
      'status': 'error', 
      'message': 'Function takes two parameters: ' 
         'id of the entry to be removed; csrf token', 
     }) 

    category = Category.query.get_or_404(id) 
    if category.posts.count(): 
     status = 'warning' 
     message = "Category '{0}' is not empty and cannot be removed".\ 
        format(category.title) 
    else: 
     status = 'success' 
     message = "Category '{0}' has been removed".\ 
        format(category.title) 
     db.session.delete(category) 
    return jsonify({ 
     'status': status, 
     'message': message, 
    }) 

<script> 
$('.remove').click(function() { 
    var data = {}; 
    data['csrf'] = $('#csrf-removal').val() 
    data['id'] = $(this).data('id-removal'); 

    $.ajaxSetup({ 
    beforeSend: function(xhr, settings) { 
      if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) { 
     xhr.setRequestHeader("X-CSRFToken", data['csrf']) 
      } 
    } 
    }); 

    var remove = confirm('Are you sure?'); 
    if (remove == true) { 
    $.ajax({ 
      url: "{{ url_for('ctrl.remove_category', _external=True) }}", 
      type: 'post', 
      dataType: 'json', 
      contentType: 'application/json;charset=UTF-8', 
      data: JSON.stringify(data, null, '\t'), 
     success: function(response) { 
     // message to user 
     var flash = "<div class='alert alert-" + response['status'] + "'>" + 
        "<button type='button' class='close' data-dismiss='alert'>&times;</button>" + 
        response['message'] + "</div>"; 
     // save message to localStorage 
     window.onbeforeunload = function() { 
      localStorage.setItem('message', flash); 
     } 
     // reload the page 
     location.reload(); 
     // jump to the top of the page 
     $('html,body').scrollTop(0); 
      }, 
      error: function(jqXHR, textStatus, errorThrown) { 
     console.log('Error code: ' + jqXHR.status); 
      } 
    }); 
    } 
}); 
</script> 

は、これは私のビュー関数です。 私はjsに関連するjavascriptとクロスブラウザの事柄にとても新しいので、どんな助けもありがとうございます。

P.S.私はthis topicを知っていますが、acceptsと 'application/json'をajax呼び出しで使用しても助けになりませんでした。

UPDATE: FirefoxでクロムとFirebugの中デベロッパーツールを使用して、私はcURLのコマンドとして両方のブラウザからのPOSTリクエストをコピーして、その結果を比較した:

  1. クロム(gistを参照してください)予想は、サーバーが取得するように動作します要求を送信し、応答を送信します。

  2. Firefox(gist参照)は機能しません。要求は送信されましたが、応答は受信されません。 cURL' is hanging untill I terminate it with^C '。 - [09/7月/ 2016年午後02時29分01秒] "POST/CTRL /削除カテゴリのHTTP/1.1" 400

-

127.0.0.1:終了時に私はWerkzeugウェブサーバがエラー400を返し、ログを参照してください

+0

を使用しています戻ってくるもの自分でjsonを書く必要があるかもしれません。例: '{'id': '5'、 'csrf': '1'}'。それでも何も表示されない場合は、[Fiddler](http://www.telerik.com/fiddler)を試して、ChromeとFirefoxのリクエスト/レスポンスの違いを比較してください。 – Miro

+0

@Miroありがとうございます。私は 'httpie'や' cURL'のようなコンソールツールにもっと慣れており、 'RESTClient'と同じ機能を持っていると思われます。 Windowsの場合と同じように、私は「Fiddler」を使うことはできません。 実際にFFとChromiumの両方のリクエストを調査し、回答を更新しました。私はまだ何が悪いのか分からない – vrs

答えて

0

さて、問題が見つかりました。

このbug reportを読んだ後、jQuery 2.1.1にアップグレードしました。その結果、404ではなくエラーコード0が返されました。ステータスコード0は、AJAX応答(see this SO topic)を取得する前にスクリプトがページをリロードすることを意味します。

だから私は、ページをリロードする前に1秒の遅延のためsetTimeoutを追加しました:

setTimeout(function() { // wait 1 sec 
    location.reload(); // reload page 
    $('html,body').scrollTop(0); // jump on top 
}, 1000); 

そして、それはトリックをしました。

P.S. setTimeoutは、問題が解決するかどうかを確認する一時的な回避策です。そのようなことを行うための正しい方法は、Firefoxのための[RESTClient](https://addons.mozilla.org/en-US/firefox/addon/restclient/)アドオンを試してみて、見約束see jQuery.when/done

関連する問題