こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

javascriptからURLに含まれる日本語のクエリを渡す方法

外部ドメインのURLをjavascriptからcgiに渡して、帰ってきた結果をjavascriptで受け取るAjaxのプログラムなのですが、
UTF8でURLエンコーディングされた日本語を引数としてcgiに渡す時に「16進数で記述してください」というjavascriptのエラーが出て実行されません。
javascriptから日本語のクエリをうまく渡せる記述方法はありませんでしょうか。

下は「東京地裁」の場合です。
http://d.hatena.ne.jp/keyword/%c5%ec%b5%fe%c3%cf%ba%db?mode=rss

クライアント側javascript全文は以下の通りです。エラーの箇所は6行目です。

<div id="rss_field" style="border:1px solid red; background:#f99">LOADING...</div><script>
window.onload = function(){
var s = document.getElementsByTagName("head")[0].appendChild(document.createElement("script"));
s.type = "text/javascript";
s.charset = "utf-8";
s.src = "http://d.hatena.ne.jp/keyword/%c5%ec%b5%fe%c3%cf%ba%db?mode=rss";
}

var xml = {};
xml.onload = function(data){
var items = data["item"];
if(items.length == 0) return;
var h = "<ul>\n";
for(var i = 0; i < Math.min(items.length, 20); i++){
var item = items[i];
if(typeof(item["description"]) == "object") item["description"] = "";
if(typeof(item["title"]) == "object") item["title"] = "";
h += "<li><a href=\"" + item["link"] + "\" title=\"" + item["description"] + "\">" + item["title"] + "</a></li>\n";
}
h += "</ul>";
document.getElementById("field").innerHTML = h;
}
</script>

うまい回避策などあれば教えていただけませんでしょうか。
参考ページ
http://tech.nitoyon.com/javascript/xml2json.html

投稿日時 - 2006-09-22 16:06:33

QNo.2424010

すぐに回答ほしいです

質問者が選んだベストアンサー

#1>WinIEでは「16進数を指定してください」というエラーが出て動作しません。
CGI プログラムでDumper を使って処理しているために、
多バイト文字(日本語部分)が
\x{HHHH} のように出力されています。
Firefox では、(この部分で)エラーにはならないようですが、
IEではエラーになります。
$json=~s/^\$VAR1/$var.data/;
$json=~s/([^\\])" => ("|{|\[)/$1" : $2/g;
の次に
$json =~ s/\\x{([0-9a-f]{4})}/\\u$1/g;
とすることで、javascript で扱えるユニコード文字指定に変換すればIEでもFirefox でも扱える文字列になります。
また、値が数値の時(ハテナスコアとか)に => が変換されないので、javascript の構文エラーになります。(これに関してはFirefox でもエラーになります)
さらに追加で
$json=~s/(".*?") => (\d*)/$1 : $2/g;
とか(数値を厳密にマッチしているわけでないので、まずい場合があります。単純に => を : に置き換えるのもありかもしれません。)します。
CGIの方は以上のように修正を加える必要があります。
また、スクリプトの方ですが
item が1つの時には配列にならないということを注意する必要があります。

投稿日時 - 2006-09-23 20:47:22

お礼

大変親切かつグレートなご回答をいただき、感激しています。上記の通りにcgiを書き換えたらIEでも動作するようになりました。ご指摘の通り、今までのRSSのキャッシュは\x{HHHH}のように出力されていましたが、それが改善され、エンコードされた日本語が引数に含まれていてもきちんと表示されています。

しかし今度は、アルファベットのみの引数の場合(例としては「star」)に「16進数を指定してください」エラーがWinIEで出力されてしまいます。FireFoxでは問題なく表示されます。
お礼が先と思い、まだよく自分で調査できていないところ恐縮ですが、お心あたりがあればご指摘いただけると幸いです。いずれにせよ、締め切る際にはBLUEPIXYさんの回答を最高に参考になったとボタン押下させていただくつもりです。

itemが1つのときに問題が出る(nullになる)のはクライアント側でif文を使って別の表示をさせるなど対策してみます。

投稿日時 - 2006-09-24 18:07:57

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

#4>具体的に、ダメなのはこれです(star)
u の上にポッチが2つの文字が未変換\x{FC}の為ですね。
aiko の方は、°みたいなヤツがだめみたいですね。
とりあえず、
$json =~ s/\\x{([0-9a-f]{4})}/\\u$1/g;
の次に
$json =~ s/\\x{([0-9a-f]{2})}/\\u00$1/g;
として2桁のやつも変換するようにしてみたらどうでしょうか

投稿日時 - 2006-09-26 02:57:08

お礼

2桁に加え3桁も変換するようにしてみたところ、完全にうまくいきました!!
どういうことだったのか、やっと少し全貌が見えてきた感じです。

当初の趣旨を外れた形で長々と質問させていただいたにも関わらず解決まで導いていただき、本当に感謝しています。ありがとうございました。

投稿日時 - 2006-09-27 22:44:22

ANo.4

#2>アルファベットのみの引数の場合(例としては「star」)に「16進数を指定してください」エラーがWinIEで出力されてしまいます
すいません、想像力が欠如していますので、そのような現象の発生するRSS(質問文のRSSでは発生しませんよね?)のURLを教えてください。

投稿日時 - 2006-09-25 15:16:59

補足

すいません、じっくり見てみたところ、色々誤解していました。cgiにリクエストしてキャッシュされたデータを受け取る時にユニコードに変換するためcgiを書き換える必要があったということですね。

実際にはクライアント側からcgiを呼ぶときに
s.src = "http://***/xml2json.cgi?url=http%3A%2F%2Fd.hatena.ne.jp%2Fkeyword%2F%E6%9D%B1%E4%BA%AC%E5%9C%B0%E8%A3%81%3Fmode%3Drss";
というように解説ページの通りの呼び方をしています。

具体的に、ダメなのはこれです(star)
url=http%3A%2F%2Fwww.*******.com%2Frss%2Ftag%2Fstar.rss

でもこれだと大丈夫です(滝川クリステル)
url=http%3A%2F%2Fwww.*******.com%2Frss%2Ftag%2F%E6%BB%9D%E5%B7%9D%E3%82%AF%E3%83%AA%E3%82%B9%E3%83%86%E3%83%AB.rss

ダメなやつでも引数のURLをブラウザからじか打ちすると表示されます。オブジェクトがNullというわけでもありません。組み合わせを色々試してみたのですが「aiko=NG」「プレイステーション=NG」「クーデター=OK」「マジンガーZ=OK」と法則が読めません。いずれもNullではありません。何卒ご指導いただけましたら幸いです。

投稿日時 - 2006-09-25 23:11:56

ANo.3

#2>$json=~s/(".*?") => (\d*)/$1 : $2/g;
は、
$json=~s/(".*?") => ([^\s]+?)/$1 : $2/g;
でいいかも

投稿日時 - 2006-09-23 20:52:31

ANo.1

他の部分は見てないんですけど
>下は「東京地裁」の場合です。
「%C5%EC%B5%FE%C3%CF%BA%DB」の部分、EUC-JPでURLENCODEされてるようですけど・

投稿日時 - 2006-09-23 01:42:14

補足

すみません、色々と間違っていました。
URLエンコードはご指摘のようにEUC-JPでした。
ただ挙動としてはこれで問題ありません。

日本語をエンコードして織り交ぜたURLでクエリをcgiに渡すところにエラーが出ていると考えていましたが、とってきたRSSが所定の場所にキャッシュとして格納されているのを確認したので、問題が別の場所にあるとの結論に達しました。

投稿日時 - 2006-09-23 12:24:43

お礼

すいません、二転三転してグダグダになってしまいましたが、WindowsのFireFoxでは上記のスクリプトで完全に動作するのですが、WinIEでは「16進数を指定してください」というエラーが出て動作しません。

なので、上記のプログラムがIEでも動作するようなアドバイスをいただければ幸いです。

投稿日時 - 2006-09-23 19:03:39

あなたにオススメの質問