JSONで応答するAjaxリクエストを作成したいと思います。だから私はこのAjaxリクエストをしました:
$.ajax({
url: 'http://my_url',
dataType: "json",
success: function(data){
alert('success');
},
error: function(data){
alert('error');
},
complete: function(data) {
alert('complete')
}})
このコードは正常に機能しますが、URLからHTTPコード404が送信されると、完全なコールバックであっても、コールバックは使用されません。調査の結果、dataTypeが 'json'であるため、404 returnがHTMLであり、JSON解析が失敗したためです。したがって、コールバックはありません。
404が発生したときにコールバック関数を呼び出すソリューションはありますか?
編集:完全なコールバックは呼び出さないで戻りは404です。404を使用したURLが必要な場合は、次のように呼び出すことができます: http://Twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_= 1269278536697 このURLに問題があります。
$.ajax({
url: 'http://Twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
dataType: "json",
success: function(data) {
alert('success');
},
error: function(data) {
alert('error');
},
complete: function(xhr, data) {
if (xhr.status != 0)
alert('success');
else
alert('fail');
}
})
構成では、jQueryは jsonp を使用してデータを転送します。これは、スクリプト要素を動的に挿入し、URLを指定された値に設定することで機能します。サーバーから返されたデータはJavaScriptとして評価され、通常は提供されたコールバックを呼び出します。サーバーが404を返す場合、コンテンツは明らかにJavaScriptではなく、コールバックは呼び出されません。一部のブラウザは、このような状況で呼び出されるスクリプトタグのエラーハンドラをサポートしています。残念ながら、IEはこれをサポートしていません。エラーを検出する最良の方法は、タイムアウトに依存することです。
あなたの場合、追加のtimeout
オプションを指定する必要があります。これにより、コールバックが時間内に呼び出されなかった場合にエラーハンドラーが呼び出されます(これは404応答の場合です)。
$.ajax({
url: 'http://my_url',
timeout: 2000, // 2 seconds timeout
dataType: "json",
success: function(data){
alert('success');
},
error: function(data){
alert('error');
},
complete: function(data) {
alert('complete')
}
});
Javascriptとjsonpを使用してTwitterAPIにアクセスする際のエラーを処理する場合は、リクエストにパラメーターsuppress_response_codes
を含める必要があります。これにより、TwitterAPIからのすべての応答が200 OK
応答で応答し、エラーが含まれます。次に、応答にerror
パラメーターが含まれているかどうかを確認する必要があります。
$.ajax({
url: "https://api.Twitter.com/1/users/show.json",
dataType: 'jsonp',
jsonp: "callback",
data: {
screen_name: "simongate1337",
suppress_response_codes: true // <- Important part
},
success: function(data) {
if(data.error) {
console.log("ERROR: "+data.error);
} else {
console.log("Success, got user " + data.screen_name);
}
}
});
statusCode
-オプションを使用する
$.ajax({
url: 'http://my_url',
dataType: "json",
statusCode: {
404: function() {
alert("I could not find the information you requested.");
}
},
success: function(data) {
alert('success');
},
error: function(data) {
alert('error');
},
complete: function(data) {
alert('complete');
}
})
問題はdataTypeにあるのではなく、許可されていないクロスドメインリクエストにあると思いませんか?
以下のコードは、同じドメインからデータをリクエストする場合は期待どおりに機能し、クロスドメインリクエストを行う場合は機能しません。
function handle404(xhr){
alert('404 not found');
}
function handleError(xhr, status, exc) {
// 0 for cross-domain requests in FF and security exception in IE
alert(xhr.status);
switch (xhr.status) {
case 404:
handle404(xhr);
break;
}
}
function dumbRequest() {
var url = 'http://Twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697';
url = 'http://Twitter.com/';
url = '/mydata.json';
// url = 'mydata.json';
$.ajax(
{url: url,
dataType: 'json',
error: handleError}
);
}
HTTPステータスが404であっても、実際の本文は有効なJSONであることをご存知ですか?たとえば、 このリンク には次のJSONがあります。
jsonp1269278524295({"request":"/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697","error":"Not found"})
そのため、通常のコールバック関数内でデータにerror
プロパティがあるかどうかを確認する必要があります。
[〜#〜] update [〜#〜]:どうやら、ページの実際のコンテンツは有効なJSONですが、ブラウザー(チェックインしました) Firefox)はそれを実行していません。おそらく404であるためです。jQueryはscript
要素を追加する必要があるため(クロスドメインの問題のため)、そのJSONPラッパーは呼び出されず、結果として、どちらもあなたのコールバックではありません。
つまり、スクリプト要素を手動で追加し、事前定義されたコールバック関数が後で呼び出されたかどうかを確認せずに、これに対処する方法はないと思います。
同じ問題に直面し、 別の質問 が jQuery-JSONP(jQuery Plugin) 404エラーのキャッチをサポートしている、または次のように説明しているのを見ました: "ネットワーク障害または不正な形式のJSON応答の場合のエラー回復 "
そしてそれは完璧に動作します:)
JSONPを介してYouTubeビデオの詳細を取得するための私の(簡略化された)コードは次のとおりです。
$.jsonp(
{
url: "https://gdata.youtube.com/feeds/api/videos/ee925OTFBCA",
callbackParameter: "callback",
data:
{
alt: "jsonc-in-script",
v: "2"
},
success: function(json, textStatus)
{
console.log("WEEEEEEEE!");
},
error: function(xOptions, textStatus)
{
console.error(arguments);
}
});
dataType
が「json」に設定されているからですか?その場合は、それをtext
に変更して、JSONを自分で評価してみてください。
$.ajax({
url: 'http://Twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
dataType: 'text',
success: function(data, status, xmlHttp) {
try {
data = eval('(' + data + ')');
alert('success');
} catch (e) {
alert('json parse error');
}
},
error: function(xmlHttp, status, error) {
alert('error');
},
complete: function(xmlHttp, status) {
alert('complete');
}
});
これが私がこれに対処する方法です。返されたデータを使用する前に、エラーがないか確認します。以下に示すのは、要件にさらに厳密に一致するように拡張できるサンプルにすぎません。これは、セッションのタイムアウトやその他のシナリオも考慮します...
私の最初の電話:
$.ajax({ type: 'POST',
url: '../doSomething',
data: 'my data',
success: function(data) {
if (HasErrors(data)) return;
var info = eval('(' + data + ')');
// do what you want with the info object
},
error: function(xmlHttpRequest) {
ReportFailure(xmlHttpRequest);
}
});
そして、2つのヘルパー関数:
function HasErrors(data) {
if (data.search(/login\.aspx/i) != -1) {
// timed out and being redirected to login page!
top.location.href = '../login.aspx';
return true;
}
if (data.search(/Internal Server Error/) != -1) {
ShowStatusFailed('Server Error.');
return true;
}
if (data.search(/Error.aspx/) != -1) {
// being redirected to site error reporting page...
ShowStatusFailed('Server Error. Please try again.');
return true;
}
return false;
}
そして
function ReportFailure(msg) {
var text;
if (typeof msg == 'string') {
text = msg;
}
else if (typeof msg.statusText == 'string') {
if (msg.status == 200) {
text = msg.responseText;
}
else {
text = '(' + msg.status + ') ' + msg.statusText + ': ';
// use the Title from the error response if possible
var matches = msg.responseText.match(/\<title\>(.*?)\<\/title\>/i);
if (matches != null)
{ text = text + matches[1]; }
else
{ text = text + msg.responseText; }
}
}
// do something in your page to show the "text" error message
$('#statusDisplay')
.html('<span class="ui-icon ui-icon-alert"></span>' + text)
.addClass('StatusError');
}
次の解決策は私にとってはうまく機能しています:)
$.ajax({
url: 'http://my_url',
dataType: "json",
success: function(data){
alert('success');
},
error: function(data){
alert('error');
},complete: function(xhr, data) {
if(data==="parsererror"){
alert('404');
}
}
});