HTTP通信でxmlを出力するプログラムを作りたいのですが、
javascript文字化けエラーになります。
【プログラム】
var request = new XMLHttpRequest();
request.open("GET", "http://www.geocoding.jp/api/?q=tokyo");
request.send(null);
【エラー】
エラー:uncaught exception:XML HttpRequest:open 文字化け
http://www.geocoding.jp/api/
のサイトは自分のHPではなく、
q=住所やランドマーク名
から経度、緯度を検索してXML形式で返すAPIなのですが
【xmlの出力結果】
http://www.geocoding.jp/api/?q=tokyo
文字化けエラーが出てxml出力することが出来ません。
このサイトに
リクエスト送信時の文字コードは UTF-8
と書かかれているため、
ソースのヘッダー、ファイルの文字コードはUTF-8にしています。
このエラーについて、
何か分かる人がいましたら教えてください。
お願いしますm(_ _)m
JavaScriptって別サーバのCGIやXMLのロードはセキュリティ的に出来ないような仕組みになっていたように思うのですがどうでしょう。
自分のサーバに"http://www.geocoding.jp/api/?q=tokyo"からデータを取ってきてJavaScriptにそのままデータを渡すCGIなどを用意し、JavaScriptにそのデータを渡すという仕組みにしないと動かないとおもいます。(同内容のXMLをスクリプト+HTMLがあるサーバに置いて動かし、返ってくるようならスクリプト自体は正常です。)
的はずれな回答ならすみません。
やはり、ドメインが異なるからではないでしょうか??
■[Javascript] XMLHttpRequest.openでは他のドメインのリソースにはアクセスできない
http://d.hatena.ne.jp/kidd-number5/20060410/1144647351
(エラーメッセージがhiyarihatto様のと少々異なっています。)
※私の環境では、異なるドメインにすると、openで返ってきませんでした。(IIS+ASP+IE6)
ブラウザによって、メッセージ内容や動作が異なるんでしょうか。
※[Microsoft.XMLDOM]で同様な事をしても駄目でした。
※デスクトップ等に配置したhtmlからだと、正常に取得できました。
※セキュリティ上まずいからでしょうね。
自分のプログラムが信用できないので、
すぐに自分のせいだと思ってしまうのですが、
セキュリティのせきみたいですね。
ありがとうございます。
「エラー: uncaught exception: Permission denied to call method XMLHttpRequest.open」
僕の環境では文字化けせずに↑このメッセージになりました。
Permission denied つまり、許可されない権限ということです。
これが出来てしまうと、あるページを見ただけで2chに書き込ませたり、amazonにアクセスさせて本名を盗んだりとかが出来てしまうわけです。
http://www.hawk.34sp.com/stdpls/xml/xmlhttprequest.html
↑ここに「セキュリティ上の配慮から、XMLHttpRequestがリクエストを送信できるのは同一ドメイン内に制限されています。」とあります^^
レスありがとうございます。
この処理が出来たら、色々危ないみたいですね。
勉強になりました。
ご要望にお応えしてCGIでの実装について追記しておきます。
たとえばPHPを用いたCGIで、"get.php"という名前で以下の内容を記述したスクリプトを作ります。
<?php @readfile("http://www.geocoding.jp/api/?q=".($_GET["q"])); ?>
JavaScript側からは"get.php"を呼びだします。そしてパラメータとしてqを付けます
例:"get.php?q=tokyo"
"get.php?q=tokyo"は"http://www.geocoding.jp/api/?q=tokyo"の情報を、"get.php?q=oosaka"なら"http://www.geocoding.jp/api/?q=oosaka"の情報をロードして呼び出し元に出力してくれます。(readfileはファイル内容を開いて表示してくれる関数です。)
JavaScriptから呼ばなくても出力内容が見れるので試してみてください。ただ、ブラウザの解釈的にはあくまでHTMLなので、XML内容はソースを見なければわかりませんのでご注意。
JavaScriptは自分のサーバにおいてあるファイルは読み込むことが出来るので、CGIを使いJavaScriptに「自分のサーバのデータだ」という風に見せかけてしまえば自由にデータをロードできるというわけです。(ちなみにJavaScriptから見れば、CGIが吐くデータも静的HTMLファイルも区別がありません。)
ありがとうございます。
kazu1107 さんのようにやりましたら、
情報を取得することが出来ました。
>>ブラウザの解釈的にはあくまでHTMLなので、XM>>L内容はソースを見なければわかりませんのでご注意。
HTMLからXML情報を取得する方法を調べたのですが、分かりません。(> <)
正規表現を使って<タグ></タグ>で囲まれた文字だけ取り出すというこのなのですかね?
もし分かる人がいましたら、
教えてください。
お願いしますm(_ _)m
-------------------------------------
http://www.geocoding.jp/api/?q=tokyo
が自サーバなら、下のようなソースでxml情報を取得しています。
request.open("GET", "http://www.geocoding.jp/api/?q=tokyo");
request.send(null);
var xmlDoc = request.responseXML;
var result = xmlDoc.documentElement.getElementsByTagName("result");
私の説明が悪かったようですみません…開かれたページのソースはご覧になられましたでしょうか?
まんまXMLのソースだと思います。
最近のブラウザはXMLを整形して表示する機能が付いてますけど、その機能が作動してないので表示するブラウザはその文章をHTMLとして解釈してるってことです。JavaScriptはそんなことお構いなしに処理するとおもうので心配いりません。
どうしても気持ち悪いときは以下のようにしてみてください。
PHP側の処理一行目に"Header("Contents-type: text/xml")"という文を加えるとブラウザからもXMLとして扱ってくれるかもしれません。
レスありがとうございますm(_ _)m
ページのソースは、まんまXMLになります。
が、HTMLと解釈しているためか、下のソースの
※のところ var xmlDoc = request.responseXML;
で、値が渡されず、xmlDocがnullになってしまいます。
そのため、XMLのタグデータを取得することができません。
★ソース
var request = new XMLHttpRequest();
req=request.open("GET", "get.php?q=tokyo" , true);
request.send(null);
request.onreadystatechange = function() {
if (request.readyState == 4) {
window.alert(request.responseText); //レスポンスデータを表示します。
var xmlDoc = request.responseXML; ※上手くいかない
alert(xmlDoc);
}
}
-----------------------------------------------------------
get.php?q=tokyo
をブラウザにベタ打ちして、表示されたXMLをコピーし別ファイルにして(test.xmlとする)
ソース2行目で
req=request.open("GET", "get.php?q=tokyo" , true);
とすると、ソースの※の所で上手くいき、
xmlDocには[object XML Document]が入り、
タグ情報を取得することが可能なのですが。
分かり人がいましたら、
教えて下さい。
お願いしますm(_ _)m
上の★のソースのあるHTMLファイルを
http://www.peacelove.biz/pg/hatena/test.html
get.php?q=tokyoの出力結果をコピーしたXMLファイルを
http://www.peacelove.biz/pg/hatena/test.xml
にアップしました。参考にしていただけると幸いです。
レスありがとうございます。
どうやら、セキュリティ的に出来ないみたいですね…
>> 自分のサーバに"http://www.geocoding.jp/api/?q=tokyo"からデータを取ってきて…
このAPIを使って緯度経度情報を取得することが可能なんですか?
すみません、勉強不足でこれがどういう処理なのか分かりません。
もし可能でしたら、教えてくださいm(_ _)m