私は JavaScript の専門家にはほど遠く、SOAP サービスを呼び出す JS コードを維持する必要があります。呼び出しは、cxf-utils.js スクリプトによって実行されます。Safari では正常に動作しますが、Firefox や Chrome では動作しません。次に、アプリケーションの直感、関連するスクリプトのスケッチ、およびコードの詳細を示します。
アプリケーションの直感
このアプリケーションでは、次の URL からアクセスできる SOAP サービスから合成された友達の場所を取得することで、マップ内の「友達」の場所を継続的に追跡できます。
http://127.0.0.1:9884/hqoutput?
このようなサービスは、友人の場所のコレクションを JSON 形式で提供します。
実装スケッチ
このアプリケーションは、次の 3 つの JS で構成されています。
map.js : マップ ビューを処理し、マップ内にフレンドのマーカーを描画し、モデルへの要求を制御します (つまり、 HQOutputImplService.js)。
HQOutputImplService.js : サービス呼び出しを準備し、サービスからの応答を処理します (つまり、(デ) シリアル化、onsuccess、および onerror 関数)。
cxf-utils.js : ブラウザーの互換性と XML 管理を提供します ( http://cxf.apache.org/docs/javascript-client-code.htmlを参照 ) 。
コードの詳細
index.html
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>My first map</title>
<link type="text/css" href="css/style.css" rel="stylesheet" media="all" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script>
<script type="text/javascript" src="js/map.js"></script>
<script type="text/javascript" src="js/cxf-utils.js"></script>
<script type="text/javascript" src="js/HQOutputImplService.js"></script>
</head>
<body>
<div id="map"></div>
</body>
</html>
map.js
(function() {
window.onload = function() {
var outputServ = new hybridqp_hadas_lig_org__HQOutput();
outputServ.url = "http://127.0.0.1:9884/hqoutput?";
// Creating a reference to the mapDiv
var mapDiv = document.getElementById('map');
var myPosLat = 48.85889;
var myPosLon = 2.29583;
// Creating a latLng for the center of the map
var latlng = new google.maps.LatLng(myPosLat, myPosLon);
// Creating an object literal containing the properties
// we want to pass to the map
var options = {
center: latlng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Creating the map
var map = new google.maps.Map(mapDiv, options);
// Adding a marker to the map
var marker = new google.maps.Marker({
position: new google.maps.LatLng(myPosLat, myPosLon),
map: map,
title: 'My Position',
icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/blue/blank.png'
});
var circleOptions = {
center: latlng,
radius: 2000,
map: map
};
// Creating the map
var circle = new google.maps.Circle(circleOptions);
// Colors used to display friends' markers
var colors = new Array('green', 'orange', 'pink', 'red');
// Color to assign to the next friend, rotates modulo the length of the array
var icolor = 0;
// Associates a tuple_id with its marker, used to remove them when negative tuples arrive: tuple_id -> marker
var markers = new Array();
// Counts the number of markers on screen for a particular user: nickname -> n_markers
var markerCounter = new Array();
// Color assigned to a friend currently on screen: nickname -> color
var friendColor = new Array();
//This is the function called upon success.
function processResponse(response) {
var jsonStr = response.getReturn();
var jsonArray = eval('(' + jsonStr + ')');
if( jsonArray != null ) {
for(var i = 0; i < jsonArray.length; i++) {
addOrRemoveFriendMarker(jsonArray[i]);
}
}
}
//This is the function called for an error. -->
function reportError(error) {
alert('error ' + error);
}
function invokeHQOutput() {
outputServ.data(processResponse, reportError);
}
// Adds a marker to the screen and has side effects on additional variables
function addOrRemoveFriendMarker(friend) {
// Check whether the tuple is positive or negative
if( friend.tuple_sign == 1 ) {
//Determine the color to use, depends whether the user has currently an assigned color
if( friendColor[friend.nickname] == undefined ) {
friendColor[friend.nickname] = colors[icolor];
icolor = (icolor + 1) % colors.length;
}
var marker = new google.maps.Marker({
position: new google.maps.LatLng(friend.lat, friend.lon),
map: map,
title: friend.nickname,
icon: 'http://gmaps-samples.googlecode.com/svn/trunk/markers/' + friendColor[friend.nickname] + '/blank.png'});
// Add the marker to the array using the tuple_id
markers[friend.tuple_id] = marker;
// Increment the marker count for the user, check if the value is undefined first
if( markerCounter[friend.nickname] == undefined )
markerCounter[friend.nickname] = 1;
else
markerCounter[friend.nickname]++;
}
else if( friend.tuple_sign == -1 ){
// Remove the marker from the screen and from the markers array
//map.removeOverlay(markers[friend.tuple_id]);
markers[friend.tuple_id].setMap(null);
delete markers[friend.tuple_id];
// Decrement the counter for this friend's markers, if it has reached 0, delte the friend from the corresponding arrays
markerCounter[friend.nickname]--;
if( markerCounter[friend.nickname] == 0 ) {
delete markerCounter[friend.nickname];
delete friendColor[friend.nickname];
}
}
}
window.setInterval(invokeHQOutput, 5000);
}
})();
HQOutputImplService.js
// Definitions for schema: http://hybridqp.hadas.lig.org/
// http://127.0.0.1:9884/hqoutput?xsd=1
//
//
// Constructor for XML Schema item {http://hybridqp.hadas.lig.org/}data
//
function hybridqp_hadas_lig_org__data () {
this.typeMarker = 'hybridqp_hadas_lig_org__data';
}
//
// Serialize {http://hybridqp.hadas.lig.org/}data
//
function hybridqp_hadas_lig_org__data_serialize(cxfjsutils, elementName, extraNamespaces) {
var xml = '';
if (elementName != null) {
xml = xml + '<';
xml = xml + elementName;
if (extraNamespaces) {
xml = xml + ' ' + extraNamespaces;
}
xml = xml + '>';
}
if (elementName != null) {
xml = xml + '</';
xml = xml + elementName;
xml = xml + '>';
}
return xml;
}
hybridqp_hadas_lig_org__data.prototype.serialize = hybridqp_hadas_lig_org__data_serialize;
function hybridqp_hadas_lig_org__data_deserialize (cxfjsutils, element) {
var newobject = new hybridqp_hadas_lig_org__data();
cxfjsutils.trace('element: ' + cxfjsutils.traceElementName(element));
var curElement = cxfjsutils.getFirstElementChild(element);
var item;
return newobject;
}
//
// Constructor for XML Schema item {http://hybridqp.hadas.lig.org/}dataResponse
//
function hybridqp_hadas_lig_org__dataResponse () {
this.typeMarker = 'hybridqp_hadas_lig_org__dataResponse';
this._return = null;
}
//
// accessor is hybridqp_hadas_lig_org__dataResponse.prototype.getReturn
// element get for return
// - element type is {http://www.w3.org/2001/XMLSchema}string
// - optional element
//
// element set for return
// setter function is is hybridqp_hadas_lig_org__dataResponse.prototype.setReturn
//
function hybridqp_hadas_lig_org__dataResponse_getReturn() { return this._return;}
hybridqp_hadas_lig_org__dataResponse.prototype.getReturn = hybridqp_hadas_lig_org__dataResponse_getReturn;
function hybridqp_hadas_lig_org__dataResponse_setReturn(value) { this._return = value;}
hybridqp_hadas_lig_org__dataResponse.prototype.setReturn = hybridqp_hadas_lig_org__dataResponse_setReturn;
//
// Serialize {http://hybridqp.hadas.lig.org/}dataResponse
//
function hybridqp_hadas_lig_org__dataResponse_serialize(cxfjsutils, elementName, extraNamespaces) {
var xml = '';
if (elementName != null) {
xml = xml + '<';
xml = xml + elementName;
if (extraNamespaces) {
xml = xml + ' ' + extraNamespaces;
}
xml = xml + '>';
}
// block for local variables
{
if (this._return != null) {
xml = xml + '<return>';
xml = xml + cxfjsutils.escapeXmlEntities(this._return);
xml = xml + '</return>';
}
}
if (elementName != null) {
xml = xml + '</';
xml = xml + elementName;
xml = xml + '>';
}
return xml;
}
hybridqp_hadas_lig_org__dataResponse.prototype.serialize = hybridqp_hadas_lig_org__dataResponse_serialize;
function hybridqp_hadas_lig_org__dataResponse_deserialize (cxfjsutils, element) {
var newobject = new hybridqp_hadas_lig_org__dataResponse();
cxfjsutils.trace('element: ' + cxfjsutils.traceElementName(element));
var curElement = cxfjsutils.getFirstElementChild(element);
var item;
cxfjsutils.trace('curElement: ' + cxfjsutils.traceElementName(curElement));
cxfjsutils.trace('processing return');
if (curElement != null && cxfjsutils.isNodeNamedNS(curElement, '', 'return')) {
var value = null;
if (!cxfjsutils.isElementNil(curElement)) {
value = cxfjsutils.getNodeText(curElement);
item = value;
}
newobject.setReturn(item);
var item = null;
if (curElement != null) {
curElement = cxfjsutils.getNextElementSibling(curElement);
}
}
return newobject;
}
//
// Definitions for service: {http://hybridqp.hadas.lig.org/}HQOutputImplService
//
// Javascript for {http://hybridqp.hadas.lig.org/}HQOutput
function hybridqp_hadas_lig_org__HQOutput () {
this.jsutils = new CxfApacheOrgUtil();
this.jsutils.interfaceObject = this;
this.synchronous = true;
this.url = null;
this.client = null;
this.response = null;
this.globalElementSerializers = [];
this.globalElementDeserializers = [];
this.globalElementSerializers['{http://hybridqp.hadas.lig.org/}data'] = hybridqp_hadas_lig_org__data_serialize;
this.globalElementDeserializers['{http://hybridqp.hadas.lig.org/}data'] = hybridqp_hadas_lig_org__data_deserialize;
this.globalElementSerializers['{http://hybridqp.hadas.lig.org/}dataResponse'] = hybridqp_hadas_lig_org__dataResponse_serialize;
this.globalElementDeserializers['{http://hybridqp.hadas.lig.org/}dataResponse'] = hybridqp_hadas_lig_org__dataResponse_deserialize;
this.globalElementSerializers['{http://hybridqp.hadas.lig.org/}data'] = hybridqp_hadas_lig_org__data_serialize;
this.globalElementDeserializers['{http://hybridqp.hadas.lig.org/}data'] = hybridqp_hadas_lig_org__data_deserialize;
this.globalElementSerializers['{http://hybridqp.hadas.lig.org/}dataResponse'] = hybridqp_hadas_lig_org__dataResponse_serialize;
this.globalElementDeserializers['{http://hybridqp.hadas.lig.org/}dataResponse'] = hybridqp_hadas_lig_org__dataResponse_deserialize;
}
function hybridqp_hadas_lig_org__data_op_onsuccess(client, responseXml) {
console.log('(hybridqp_hadas_lig_org__data_op_onsuccess)');
if (client.user_onsuccess) {
var responseObject = null;
var element = responseXml.documentElement;
this.jsutils.trace('responseXml: ' + this.jsutils.traceElementName(element));
element = this.jsutils.getFirstElementChild(element);
this.jsutils.trace('first element child: ' + this.jsutils.traceElementName(element));
while (!this.jsutils.isNodeNamedNS(element, 'http://schemas.xmlsoap.org/soap/envelope/', 'Body')) {
element = this.jsutils.getNextElementSibling(element);
if (element == null) {
throw 'No env:Body in message.'
}
}
element = this.jsutils.getFirstElementChild(element);
this.jsutils.trace('part element: ' + this.jsutils.traceElementName(element));
this.jsutils.trace('calling hybridqp_hadas_lig_org__dataResponse_deserializeResponse');
responseObject = hybridqp_hadas_lig_org__dataResponse_deserializeResponse(this.jsutils, element);
client.user_onsuccess(responseObject);
}
}
hybridqp_hadas_lig_org__HQOutput.prototype.data_onsuccess = hybridqp_hadas_lig_org__data_op_onsuccess;
function hybridqp_hadas_lig_org__data_op_onerror(client) {
console.log('(hybridqp_hadas_lig_org__data_op_onerror)');
if (client.user_onerror) {
var httpStatus;
var httpStatusText;
try {
httpStatus = client.req.status;
httpStatusText = client.req.statusText;
} catch(e) {
httpStatus = -1;
httpStatusText = 'Error opening connection to server';
}
client.user_onerror(httpStatus, httpStatusText);
}
}
hybridqp_hadas_lig_org__HQOutput.prototype.data_onerror = hybridqp_hadas_lig_org__data_op_onerror;
//
// Operation {http://hybridqp.hadas.lig.org/}data
// Wrapped operation.
//
function hybridqp_hadas_lig_org__data_op(successCallback, errorCallback) {
this.client = new CxfApacheOrgClient(this.jsutils);
var xml = null;
var args = new Array(0);
xml = this.data_serializeInput(this.jsutils, args);
this.client.user_onsuccess = successCallback;
this.client.user_onerror = errorCallback;
var closureThis = this;
this.client.onsuccess = function(client, responseXml) { closureThis.data_onsuccess(client, responseXml); };
this.client.onerror = function(client) { closureThis.data_onerror(client); };
var requestHeaders = [];
requestHeaders['SOAPAction'] = '';
this.jsutils.trace('synchronous = ' + this.synchronous);
this.client.request(this.url, xml, null, this.synchronous, requestHeaders);
}
hybridqp_hadas_lig_org__HQOutput.prototype.data = hybridqp_hadas_lig_org__data_op;
function hybridqp_hadas_lig_org__data_serializeInput(cxfjsutils, args) {
var wrapperObj = new hybridqp_hadas_lig_org__data();
var xml;
xml = cxfjsutils.beginSoap11Message("xmlns:jns0='http://hybridqp.hadas.lig.org/' ");
// block for local variables
{
xml = xml + wrapperObj.serialize(cxfjsutils, 'jns0:data', null);
}
xml = xml + cxfjsutils.endSoap11Message();
return xml;
}
hybridqp_hadas_lig_org__HQOutput.prototype.data_serializeInput = hybridqp_hadas_lig_org__data_serializeInput;
function hybridqp_hadas_lig_org__dataResponse_deserializeResponse(cxfjsutils, partElement) {
var returnObject = hybridqp_hadas_lig_org__dataResponse_deserialize (cxfjsutils, partElement);
return returnObject;
}
function hybridqp_hadas_lig_org__HQOutput_hybridqp_hadas_lig_org__HQOutputImplPort () {
this.url = 'http://127.0.0.1:9884/hqoutput';
}
hybridqp_hadas_lig_org__HQOutput_hybridqp_hadas_lig_org__HQOutputImplPort.prototype = new hybridqp_hadas_lig_org__HQOutput;
cxf-utils.js
問題
上記の HQOutputImplService.js に示されているように、onsuccess と onerror コードがあります。スクリプトが Safari で実行されると、常に onsuccess コード (つまり、 hybridqp_hadas_lig_org__data_op_onsuccess) に到達しますが、Firefox と Chrome では、常に onerror コード (つまり、 hybridqp_hadas_lig_org__data_op_onerror) に到達します。
各ブラウザのスクリーンショットはこちら。
サファリ
ファイアフォックス
クロム
質問
実際、良い質問をどのように定式化すればよいかわかりません。だから…</p>
-手がかりを教えてください。
-何を確認すればよいですか?
- ここでさらにどのような情報を提供する必要がありますか?
更新 1
JS の実行をトレースすると、Chrome と Firefox の両方が http 応答コード「0」を取得します。さらに、Firefox の開発者コンソールはNS_ERROR_FAILUREエラーを報告します。このエラーの考えられる理由の 1 つは、異なるオリジンからデータを受信しようとしたため、同一オリジン ポリシーに違反していることです。どうやら、SOAP リクエストが localhost (ポート 9884) に対して行われ、エンベロープ、シリアライザー、名前空間がhttp://hybridqp.hadas.lig.org/にリクエストされたことが原因であると思われます。新しい質問は次のとおりです。
- 複数オリジン応答を有効にする方法はありますか?
- etc/hosts ファイルでhttp://hybridqp.hadas.lig.org/を localhost エイリアスとして定義する必要がありますか?