そのような問題は新しいものではないかもしれませんが、私は同様のものを見つけませんでした。私はそのようなjQueryコードを持っています:
$.ajax({
url : ('/people/'+id),
type : 'DELETE',
dataType : 'json',
success : function(e) {
table.getItems(currentPage);
}
});
私のRailsコントローラは次のようになります:
def destroy
@person = Person.find(params[:id])
@person.destroy
respond_to do |format|
format.html { redirect_to(people_url) }
format.json { render :json => @person, :status => :ok }
end
end
これは機能しています。
しかし、(標準で生成された)以下を使用すると、success
コールバックが呼び出されません。
def destroy
@person = Person.find(params[:id])
@person.destroy
respond_to do |format|
format.html { redirect_to(people_url) }
format.json { head :ok }
end
end
Rails 3.0.3
、jQuery 1.4.2
、Firefox 3.6.13
の下でテストされています。
Firebugは、そのクエリが実行され、どちらの場合も200 OKを返し、どちらの場合もアイテムが削除されると述べています。ただし、2番目のケースでは、コールバックは呼び出されません。
RESTに大きな違いはありますか?また、足場コントローラーを使用してjQueryを利用する方法はありますか?
私はこれに数回遭遇しましたが、答えは一見単純です。
$ .ajax呼び出しでdataType : 'json'
を使用しているため、jQueryはJSON応答を期待しています。 head :ok
Railsは、単一のスペース( http://github.com/Rails/rails/issues/1742 )を含む応答を返します。 jQueryは有効なJSONとして受け入れません。
したがって、本当にエラーまたは200 OKヘッダーのいずれかが表示されることが予想される場合は、リクエストにdataType : 'html'
を設定するだけで機能します(dataTypeを設定しない場合、jQueryはタイプが何であるかを推測しようとします応答ヘッダーなどに基づいており、jsonを推測することができますが、その場合でもこの問題が発生します)。実際にJSONが返されることを期待している場合は、head :ok
を使用する代わりに、JSONで有効なものをレンダリングするか(コメントを参照)、@ Waseemの提案に従ってhead :no_content
を使用します。
GearHeadは正しいですが、jQueryパーサーは実際には、空の文字列応答をnullとして扱い、解析しないように十分にスマートになっています。
ただし、jsonを受け取ったり、head
応答を受け取ったりする呼び出しがあり、サーバーにアクセスできない場合や、すべてのhead
呼び出しを変更したくない場合は、この代替ソリューション:
問題は、Railsがhead
を使用すると空の応答として単一のスペースを送信することです(ここを参照してください) レールで本当に空のボディを返す方法?つまりコンテンツ-長さ )
この記事の執筆時点では、jQuery parseJSON関数の関連部分は次のようになっています。
_parseJSON: function( data ) {
if ( typeof data !== "string" || !data ) {
return null;
}
// Make sure leading/trailing whitespace is removed (IE can't handle it)
data = jQuery.trim( data );
// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
_
ご覧のとおり、jQueryはデータが空の文字列beforeであるかどうかをテストしてトリミングしています。次に、コンソールでJSON.parse("")
を実行しようとするとエラーが発生し、catch
ステートメントを介してajaxエラーコールバックがトリガーされます。
簡単な修正があります。 jQueryでは、1つのデータ型が要求され、別のデータ型が返されたときに、コンバーターを使用できます。詳細については、こちらをご覧ください: http://api.jquery.com/extending-ajax/
Rails head
応答はテキストとしてレンダリングされるので、解析する前に応答をトリミングするjsonコンバーターへのテキストを定義するだけです。このスニペットを追加するだけです:
_// deal with Rails ' ' empty response
jQuery.ajaxSetup({
converters: {
"text json": function (response) {
jQuery.parseJSON($.trim(response))
}
}
})
_
これは、jQuery Validate Pluginの古いバージョンが原因である場合があります。このプラグインを使用している場合、この問題が発生することがあります。ケースに当てはまる場合、これを修正するアップデートがあります。
または、次のようにしてエラーハンドラーを設定することで、問題の原因を特定できます。
$.ajaxSetup()
または$.ajaxError()
これはおそらく解析エラーを返します。 jQueryの新しいバージョンは、JSON解析に関して非常に厳密であることで有名です。