久々にハマってしまった・・・
jQueryにまかせておけばさほどはまらなかったかもしれないが、JSでAJAX処理を個別メソッドで行なっている場合に、下記の条件でエラーになってしまって、2時間ほど費やしたので、メモしておきます。
ハマりポイント
以前の記事の自作AJAXライブラリを使っていて問題発生
[Javascript] Ajaxライブラリ
サーバーのPHPファイルにアクセスして返り値をJSONでもらって対応していたところを、JSファイルに直接アクセスして、返り値のTEXTデータをevalすると、onload処理を行わなくてもライブラリの読み込み確認ができると思い、通常通り以下の様な記述で行なった所、エラー発生!!
$$.ajax.set({
"url" :"http://hoge.com/common.js",
"method":"post",
"async" :"true",
"onSuccess":function(res){
eval(res);
}
});
これを実行した際に、以下のようなエラー発生。
load.js?k=fe01ce2…:183 POST http://192.168.33.12/job/capy/protech2/service/protech/js/common.js 405 (Not Allowed)
下のリンクページを見てみたところ、どうやら405エラーは、サーバー側のヘッダの問題のようだ・・・
status一覧表
解消方法
前回記事に、修正ポイントを書いていますが、改めて解説。
まず、ライブラリに「content-type」が「application/x-www-form-urlencoded」に固定されていたので「text/plane」または「text/javascript」を指定できるように以下ソース改修を行なった。
改修前
httpoj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
改修後
if(typeof option.type != "undefined"){
httpoj.setRequestHeader('Content-Type', option.type);
}
else{
httpoj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
分岐処理を入れただけですね。
そして、optionにtypeのkeyを追加できるようにして、呼び出し時にしていすればいい事にしました。
もう一つ分かったことがあり、「application/x-www-form-urlencoded」はサーバーでPOSTを受け入れる事ができるcontentのようで、
methodを「get」にしなければいけないので、CGIアクセス以外は、特に固定ファイルなどの呼び出しは「GET」を指定するといいようです。
呼び出し方法
$$.ajax.set({
"url" :"http://hoge.com/common.js",
"method":"get",
"async" :"true",
"type" :"text/plain",
"onSuccess":function(res){
eval(res);
}
});
ライブラリソースコード
修正版のソースコードもアップしておきます。
$$.ajax = {
createHttpRequest:function(){
//Win ie用
if(w.ActiveXObject){
//MSXML2以降用;
try{return new ActiveXObject("Msxml2.XMLHTTP")}
catch(e){
//旧MSXML用;
try{return new ActiveXObject("Microsoft.XMLHTTP")}
catch(e2){return null}
}
}
//Win ie以外のXMLHttpRequestオブジェクト実装ブラウザ用;
else if(w.XMLHttpRequest){return new XMLHttpRequest()}
else{return null}
},
/**
* XMLHttpRequestオブジェクト生成
*/
set:function(option){
if(!option){return}
var httpoj = new $$.ajax.createHttpRequest();
if(!httpoj){return;}
//open メソッド;
httpoj.open( option.method , option.url , option.async );
if(typeof option.type != "undefined"){
httpoj.setRequestHeader('Content-Type', option.type);
}
else{
httpoj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
}
//受信時に起動するイベント;
httpoj.onreadystatechange = function(){
//readyState値は4で受信完了;
if (httpoj.readyState==4){
//コールバック
option.onSuccess(httpoj.responseText);
}
};
//query整形
var data = [];
if(typeof(option.query)!="undefined"){
for(var i in option.query){
data.push(i+"="+encodeURIComponent(option.query[i]));
}
}
if(typeof(option.querys)!="undefined"){
for(var i=0;i<option.querys.length;i++){
data.push(option.querys[i][0]+"="+encodeURIComponent(option.querys[i][1]));
}
}
//send メソッド
if(data.length){
httpoj.send( data.join("&") );
}
else{
httpoj.send();
}
},
//コールバック関数 ( 受信時に実行されます );
onSuccess:function(res){console.log(res)}
};
無事にアクセスすることができるようになりました。
メデタシメデタシ・・・