Google App Engineに対するクロスドメインリクエストのgetがうまくいきません。
ちなみに、postはうまくいきます。
問題を解決するための実装方法を教えてください。
参考になるかもしれないサイトを付記しておきます。
【Google App Engineでクロスドメイン通信】
http://zafiel.wingall.com/archives/2010101816041505.php
現在の関係がありそうなコードはコメント欄に記載してあります。
当方初級レベルです。よろしくお願い致します。
コメント(6件)
var request = "http://localhost:8082/"
function postMessage(){
var content = $("#content").text()
$.post(request, {"content": content}, function(){
alert("ok");
}, "json");
}
function getMessage(){
$.get(request, {viewerid : "test"}, function(results) {
if(results.length == 0){
//pass
}
else{
//when results is an object, this "i" is a hash key.
//when results is an array, this "i" is an index.
$.each(results, function(i, result) {
$("#tweets").append("<div class='content'>" + result.content + "</div>")
});
}
}, 'json');
}
◆上記関数が記載されているiphone.jsやjquery.jsをjsonp(?)にて取り込んでいる箇所
//localhost:8082はローカルで動いているGAEのドメイン
<script type="text/javascript" src="http://localhost:8082/js/jquery.js"></script>
<script type="text/javascript" src="http://localhost:8082/js/iphone.js"></script>
◆GAEのプログラム
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import os
from google.appengine.ext.webapp import template
import wsgiref.handlers
from google.appengine.ext import db
from django.utils import simplejson
class Tweet(db.Model):
content = db.StringProperty()
class MainHandler(webapp.RequestHandler):
def get(self):
tweets = db.GqlQuery("SELECT * FROM Tweet")
results = []
for tweet in tweets:
result = {}
result["content"] = tweet.content
resluts.append(result)
self.response.out.write(simplejson.dumps(results))
def post(self):
tweet = Tweet()
tweet.content = self.request.get("content")
tweet.put()
def main():
application = webapp.WSGIApplication(
[
('/', MainHandler)
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
logging.info("mainchecker")
main()
>|javascript|
var url = 'xxxxxxxxxxxxxxxx'; // get したい所
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
if ( xhr.status == 200 ) {
console.info('Success!!');
console.dir(JSON.parse(xhr.responseText));
} else {
console.error(xhr.responseText);
}
}
};
xhr.send(null);
||<
試したところ、次のようなエラーがでました。
XMLHttpRequest cannot load localhost:8082.
Cross origin requests are only supported for HTTP.
httpならokみたいな空気だしてますが、こんなこともいってきます。
XMLHttpRequest cannot load http://localhost:8082/.
Origin null is not allowed by Access-Control-Allow-Origin.
http://zafiel.wingall.com/archives/2010101816041505.php
これがもっとも怪しいような気がしています。
上記を試しましたが、17行目のあたりでエラーが出たので早々に諦めてました。
もう一度明日試してみます。
hagino3000
@puriketu99 ドメインがlocalhost:8082のページからxxx.appspot.comへpost/getしたいという事? jQueryの$.getを使わずにコンソールから生のXMLHttpRequestを使って通信できるか試してみたらどうなる??
puriketu99
@hagino3000 phoneGapで作ったiphoneアプリ(localhost:8082からダウンロードしたファイルではなく、静的なファイル)からlocalhost:8082にpost/getしたいです XMLhttpRequestというのがわからず調査と睡魔が戦争中
例えばPCで「localhost」と指定した場合、そのPCの中にあるサーバーへデータを飛ばします。
iPhoneアプリでlocalhostと指定するとiPhoneの中にあるサーバーを指します。
つまり、貴方が書かれたコードを意図通りに動作させるためには
iPhoneの中にGoogleAppEngineサーバーを入れて動かす必要があるということです。
当然、そんなことは不可能です。
なので、まずはPythonコードをApp Engineにデプロイ(アップロード)しましょう。
デプロイが成功すると、アプリ名に応じたappspot.comのドメインでアクセスできるようになります。
その後、jsのデータ飛ばし先を
var request = "http://貴方のappspotドメイン/";
のように修正します。
アプリであればクロスドメイン指定は必要無い気もします・・・が、もしクロスドメインで引っかかるようであれば、下記Pythonコードを参考にやってみて下さい。
※スペースは全角スペースになっていますので注意して下さい。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from google.appengine.ext import db
from django.utils import simplejson
class Tweet(db.Model):
content = db.StringProperty()
class MainHandler(webapp.RequestHandler):
def get(self):
# 色々なheaderを付与
self.response.headers['Access-Control-Allow-Origin'] = '*'
# GETだけならPOST, OPTIONSは無くてもOK
self.response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
tweets = db.GqlQuery("SELECT * FROM Tweet")
results = []
for tweet in tweets:
result = {}
result["content"] = tweet.content
resluts.append(result)
self.response.out.write(simplejson.dumps(results))
def post(self):
self.response.headers['Access-Control-Allow-Origin'] = '*'
self.response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
tweet = Tweet()
tweet.content = self.request.get("content")
tweet.put()
def main():
application = webapp.WSGIApplication(
[
('/', MainHandler)
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
logging.info("mainchecker")
main()
助けになれば幸いです。