Subversion Repositories Applications.papyrus

Compare Revisions

Ignore whitespace Rev 2149 → Rev 2150

/trunk/api/js/dojo1.0/dojox/io/proxy/xip_server.html
New file
0,0 → 1,386
<!--
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
Pieces taken from Dojo source to make this file stand-alone
-->
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
<script type="text/javascript" src="isAllowed.js"></script>
<!--
BY DEFAULT THIS FILE DOES NOT WORK SO THAT YOU DON'T ACCIDENTALLY EXPOSE
ALL OF YOUR XHR-ENABLED SERVICES ON YOUR SITE.
In order for this file to work, you need to uncomment the start and end script tags,
and you should define a function with the following signature:
function isAllowedRequest(request){
return false;
}
Return true out of the function if you want to allow the cross-domain request.
DON'T DEFINE THIS FUNCTION IN THIS FILE! Define it in a separate file called isAllowed.js
and include it in this page with a script tag that has a src attribute pointing to the file.
See the very first script tag in this file for an example. You do not have to place the
script file in the same directory as this file, just update the path above if you move it
somewhere else.
Customize the isAllowedRequest function to restrict what types of requests are allowed
for this server. The request object has the following properties:
- requestHeaders: an object with the request headers that are to be added to
the XHR request.
- method: the HTTP method (GET, POST, etc...)
- uri: The URI for the request.
- data: The URL-encoded data for the request. For a GET request, this would
be the querystring parameters. For a POST request, it wll be the
body data.
See xip_client.html for more info on the xip fragment identifier protocol.
-->
<!-- Security protection: uncomment the script tag to enable. -->
<!-- script type="text/javascript" -->
// <!--
//Core XHR handling taken from Dojo IO code.
dojo = {};
dojo.hostenv = {};
// These are in order of decreasing likelihood; this will change in time.
dojo.hostenv._XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
dojo.hostenv.getXmlhttpObject = function(){
var http = null;
var last_e = null;
try{ http = new XMLHttpRequest(); }catch(e){}
if(!http){
for(var i=0; i<3; ++i){
var progid = dojo.hostenv._XMLHTTP_PROGIDS[i];
try{
http = new ActiveXObject(progid);
}catch(e){
last_e = e;
}
if(http){
dojo.hostenv._XMLHTTP_PROGIDS = [progid]; // so faster next time
break;
}
}
/*if(http && !http.toString) {
http.toString = function() { "[object XMLHttpRequest]"; }
}*/
}
if(!http){
throw "xip_server.html: XMLHTTP not available: " + last_e;
}
return http;
}
 
dojo.setHeaders = function(http, headers){
if(headers) {
for(var header in headers) {
var headerValue = headers[header];
http.setRequestHeader(header, headerValue);
}
}
}
 
//MSIE has the lowest limit for URLs with fragment identifiers,
//at around 4K. Choosing a slightly smaller number for good measure.
xipUrlLimit = 4000;
xipIdCounter = 1;
 
function xipServerInit(){
xipStateId = "";
xipCurrentHash = "";
xipRequestMessage = "";
xipResponseParts = [];
xipPartIndex = 0;
}
 
function pollHash(){
//Can't use location.hash because at least Firefox does a decodeURIComponent on it.
var urlParts = window.location.href.split("#");
if(urlParts.length == 2){
var newHash = urlParts[1];
if(newHash != xipCurrentHash){
try{
messageReceived(newHash);
}catch(e){
//Make sure to not keep processing the error hash value.
xipCurrentHash = newHash;
throw e;
}
xipCurrentHash = newHash;
}
}
}
 
function messageReceived(encodedData){
var msg = unpackMessage(encodedData);
switch(msg.command){
case "ok":
sendResponsePart();
break;
case "start":
xipRequestMessage = "";
xipRequestMessage += msg.message;
setClientUrl("ok");
break;
case "part":
xipRequestMessage += msg.message;
setClientUrl("ok");
break;
case "end":
setClientUrl("ok");
xipRequestMessage += msg.message;
sendXhr();
break;
}
}
 
function sendResponse(encodedData){
//Break the message into parts, if necessary.
xipResponseParts = [];
var resData = encodedData;
var urlLength = xipClientUrl.length;
var partLength = xipUrlLimit - urlLength;
var resIndex = 0;
 
while((resData.length - resIndex) + urlLength > xipUrlLimit){
var part = resData.substring(resIndex, resIndex + partLength);
//Safari will do some extra hex escaping unless we keep the original hex
//escaping complete.
var percentIndex = part.lastIndexOf("%");
if(percentIndex == part.length - 1 || percentIndex == part.length - 2){
part = part.substring(0, percentIndex);
}
xipResponseParts.push(part);
resIndex += part.length;
}
xipResponseParts.push(resData.substring(resIndex, resData.length));
xipPartIndex = 0;
sendResponsePart();
}
function sendResponsePart(){
if(xipPartIndex < xipResponseParts.length){
//Get the message part.
var partData = xipResponseParts[xipPartIndex];
//Get the command.
var cmd = "part";
if(xipPartIndex + 1 == xipResponseParts.length){
cmd = "end";
}else if (xipPartIndex == 0){
cmd = "start";
}
 
setClientUrl(cmd, partData);
xipPartIndex++;
}else{
xipServerInit();
}
}
 
function setClientUrl(cmd, message){
var clientUrl = makeClientUrl(cmd, message);
//Safari won't let us replace across domains.
if(navigator.userAgent.indexOf("Safari") == -1){
parent.location.replace(clientUrl);
}else{
parent.location = clientUrl;
}
}
 
function makeClientUrl(cmd, message){
var clientUrl = xipClientUrl + "#" + (xipIdCounter++) + ":" + cmd;
if(message){
clientUrl += ":" + message;
}
return clientUrl
}
 
function xhrDone(xhr){
/* Need to pull off and return the following data:
- responseHeaders
- status
- statusText
- responseText
*/
var response = {};
if(typeof(xhr.getAllResponseHeaders) != "undefined"){
var allHeaders = xhr.getAllResponseHeaders();
if(allHeaders){
response.responseHeaders = allHeaders;
}
}
if(xhr.status == 0 || xhr.status){
response.status = xhr.status;
}
if(xhr.statusText){
response.statusText = xhr.statusText;
}
if(xhr.responseText){
response.responseText = xhr.responseText;
}
//Build a string of the response object.
var result = "";
var isFirst = true;
for (var param in response){
if(isFirst){
isFirst = false;
}else{
result += "&";
}
result += param + "=" + encodeURIComponent(response[param]);
}
sendResponse(result);
}
 
function sendXhr(){
var request = {};
var nvPairs = xipRequestMessage.split("&");
var i = 0;
var nameValue = null;
for(i = 0; i < nvPairs.length; i++){
if(nvPairs[i]){
var nameValue = nvPairs[i].split("=");
request[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
}
}
 
//Split up the request headers, if any.
var headers = {};
if(request.requestHeaders){
nvPairs = request.requestHeaders.split("\r\n");
for(i = 0; i < nvPairs.length; i++){
if(nvPairs[i]){
nameValue = nvPairs[i].split(": ");
headers[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
}
}
 
request.requestHeaders = headers;
}
if(isAllowedRequest(request)){
//The request is allowed, so set up the XHR object.
var xhr = dojo.hostenv.getXmlhttpObject();
//Start timer to look for readyState.
var xhrIntervalId = setInterval(function(){
if(xhr.readyState == 4){
clearInterval(xhrIntervalId);
xhrDone(xhr);
}
}, 10);
 
//Actually start up the XHR request.
xhr.open(request.method, request.uri, true);
dojo.setHeaders(xhr, request.requestHeaders);
var content = "";
if(request.data){
content = request.data;
}
 
try{
xhr.send(content);
}catch(e){
if(typeof xhr.abort == "function"){
xhr.abort();
xhrDone({status: 404, statusText: "xip_server.html error: " + e});
}
}
}
}
 
function unpackMessage(encodedMessage){
var parts = encodedMessage.split(":");
var command = parts[1];
encodedMessage = parts[2] || "";
 
var config = null;
if(command == "init"){
var configParts = encodedMessage.split("&");
config = {};
for(var i = 0; i < configParts.length; i++){
var nameValue = configParts[i].split("=");
config[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
}
}
return {command: command, message: encodedMessage, config: config};
}
 
function onServerLoad(){
xipServerInit();
 
//Decode the init params
var config = unpackMessage(window.location.href.split("#")[1]).config;
 
xipStateId = config.id;
xipClientUrl = config.client;
//Make sure we don't have a javascript: url, just for good measure.
if(xipClientUrl.split(":")[0].match(/javascript/i)){
throw "Invalid client URL";
}
if(!xipStateId.match(/^XhrIframeProxy[0-9]+$/)){
throw "Invalid state ID";
}
 
xipUseFrameRecursion = config["fr"];
 
setInterval(pollHash, 10);
if(xipUseFrameRecursion == "true"){
var serverUrl = window.location.href.split("#")[0];
document.getElementById("iframeHolder").innerHTML = '<iframe name="'
+ xipStateId + '_clientEndPoint'
+ '" src="javascript:false">'
+ '</iframe>';
var iframeNode = document.getElementsByTagName("iframe")[0];
iframeNode.src = makeClientUrl("init", 'id=' + xipStateId + '&server='
+ encodeURIComponent(serverUrl) + '&fr=endpoint');
}else{
setClientUrl("loaded");
}
}
 
if(typeof(window.addEventListener) == "undefined"){
window.attachEvent("onload", onServerLoad);
}else{
window.addEventListener('load', onServerLoad, false);
}
// -->
<!-- </script> -->
</head>
<body>
<h4>The Dojo Toolkit -- xip_server.html</h4>
 
<p>This file is used for Dojo's XMLHttpRequest Iframe Proxy. This is the the file
that should go on the server that will actually be doing the XHR request.</p>
<div id="iframeHolder"></div>
</body>
</html>
/trunk/api/js/dojo1.0/dojox/io/proxy/xip.js
New file
0,0 → 1,236
if(!dojo._hasResource["dojox.io.proxy.xip"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.io.proxy.xip"] = true;
dojo.provide("dojox.io.proxy.xip");
 
dojo.require("dojo.io.iframe");
dojo.require("dojox.data.dom");
 
dojox.io.proxy.xip = {
//summary: Object that implements the iframe handling for XMLHttpRequest
//IFrame Proxying.
//description: Do not use this object directly. See the Dojo Book page
//on XMLHttpRequest IFrame Proxying:
//http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
//Usage of XHR IFrame Proxying does not work from local disk in Safari.
 
xipClientUrl: djConfig["xipClientUrl"] || dojo.moduleUrl("dojox.io.proxy", "xip_client.html"),
 
_state: {},
_stateIdCounter: 0,
 
needFrameRecursion: function(){
return (dojo.isIE >= 7);
},
 
send: function(facade){
var stateId = "XhrIframeProxy" + (this._stateIdCounter++);
facade._stateId = stateId;
 
 
var frameUrl = this.xipClientUrl + "#0:init:id=" + stateId + "&server="
+ encodeURIComponent(facade._ifpServerUrl) + "&fr=false";
if(this.needFrameRecursion()){
//IE7 hack. Need to load server URL, and have that load the xip_client.html.
//Also, this server URL needs to different from the one eventually loaded by xip_client.html
//Otherwise, IE7 will not load it. Funky.
var fullClientUrl = window.location.href.split("#")[0].split("?")[0];
if((this.xipClientUrl + "").charAt(0) == "/"){
var endIndex = fullClientUrl.indexOf("://");
endIndex = fullClientUrl.indexOf("/", endIndex + 3);
fullClientUrl = fullClientUrl.substring(0, endIndex);
}else{
fullClientUrl = fullClientUrl.substring(0, fullClientUrl.lastIndexOf("/") + 1);
}
fullClientUrl += this.xipClientUrl;
var serverUrl = facade._ifpServerUrl
+ (facade._ifpServerUrl.indexOf("?") == -1 ? "?" : "&") + "dojo.fr=1";
 
frameUrl = serverUrl + "#0:init:id=" + stateId + "&client="
+ encodeURIComponent(fullClientUrl) + "&fr=" + this.needFrameRecursion(); //fr is for Frame Recursion
}
 
this._state[stateId] = {
facade: facade,
stateId: stateId,
clientFrame: dojo.io.iframe.create(stateId, "", frameUrl)
};
return stateId;
},
receive: function(/*String*/stateId, /*String*/urlEncodedData){
/* urlEncodedData should have the following params:
- responseHeaders
- status
- statusText
- responseText
*/
//Decode response data.
var response = {};
var nvPairs = urlEncodedData.split("&");
for(var i = 0; i < nvPairs.length; i++){
if(nvPairs[i]){
var nameValue = nvPairs[i].split("=");
response[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
}
}
 
//Set data on facade object.
var state = this._state[stateId];
var facade = state.facade;
 
facade._setResponseHeaders(response.responseHeaders);
if(response.status == 0 || response.status){
facade.status = parseInt(response.status, 10);
}
if(response.statusText){
facade.statusText = response.statusText;
}
if(response.responseText){
facade.responseText = response.responseText;
//Fix responseXML.
var contentType = facade.getResponseHeader("Content-Type");
if(contentType && (contentType == "application/xml" || contentType == "text/xml")){
facade.responseXML = dojox.data.dom.createDocument(response.responseText, contentType);
}
}
facade.readyState = 4;
this.destroyState(stateId);
},
 
clientFrameLoaded: function(/*String*/stateId){
var state = this._state[stateId];
var facade = state.facade;
 
if(this.needFrameRecursion()){
var clientWindow = window.open("", state.stateId + "_clientEndPoint");
}else{
var clientWindow = state.clientFrame.contentWindow;
}
 
var reqHeaders = [];
for(var param in facade._requestHeaders){
reqHeaders.push(param + ": " + facade._requestHeaders[param]);
}
var requestData = {
uri: facade._uri
};
if(reqHeaders.length > 0){
requestData.requestHeaders = reqHeaders.join("\r\n");
}
if(facade._method){
requestData.method = facade._method;
}
if(facade._bodyData){
requestData.data = facade._bodyData;
}
 
clientWindow.send(dojo.objectToQuery(requestData));
},
destroyState: function(/*String*/stateId){
var state = this._state[stateId];
if(state){
delete this._state[stateId];
var parentNode = state.clientFrame.parentNode;
parentNode.removeChild(state.clientFrame);
state.clientFrame = null;
state = null;
}
},
 
createFacade: function(){
if(arguments && arguments[0] && arguments[0].iframeProxyUrl){
return new dojox.io.proxy.xip.XhrIframeFacade(arguments[0].iframeProxyUrl);
}else{
return dojox.io.proxy.xip._xhrObjOld.apply(dojo, arguments);
}
}
}
 
//Replace the normal XHR factory with the proxy one.
dojox.io.proxy.xip._xhrObjOld = dojo._xhrObj;
dojo._xhrObj = dojox.io.proxy.xip.createFacade;
 
/**
Using this a reference: http://www.w3.org/TR/XMLHttpRequest/
 
Does not implement the onreadystate callback since dojo.xhr* does
not use it.
*/
dojox.io.proxy.xip.XhrIframeFacade = function(ifpServerUrl){
//summary: XMLHttpRequest facade object used by dojox.io.proxy.xip.
//description: Do not use this object directly. See the Dojo Book page
//on XMLHttpRequest IFrame Proxying:
//http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
this._requestHeaders = {};
this._allResponseHeaders = null;
this._responseHeaders = {};
this._method = null;
this._uri = null;
this._bodyData = null;
this.responseText = null;
this.responseXML = null;
this.status = null;
this.statusText = null;
this.readyState = 0;
this._ifpServerUrl = ifpServerUrl;
this._stateId = null;
}
 
dojo.extend(dojox.io.proxy.xip.XhrIframeFacade, {
//The open method does not properly reset since Dojo does not reuse XHR objects.
open: function(/*String*/method, /*String*/uri){
this._method = method;
this._uri = uri;
 
this.readyState = 1;
},
setRequestHeader: function(/*String*/header, /*String*/value){
this._requestHeaders[header] = value;
},
send: function(/*String*/stringData){
this._bodyData = stringData;
this._stateId = dojox.io.proxy.xip.send(this);
this.readyState = 2;
},
abort: function(){
dojox.io.proxy.xip.destroyState(this._stateId);
},
getAllResponseHeaders: function(){
return this._allResponseHeaders; //String
},
getResponseHeader: function(/*String*/header){
return this._responseHeaders[header]; //String
},
_setResponseHeaders: function(/*String*/allHeaders){
if(allHeaders){
this._allResponseHeaders = allHeaders;
//Make sure ther are now CR characters in the headers.
allHeaders = allHeaders.replace(/\r/g, "");
var nvPairs = allHeaders.split("\n");
for(var i = 0; i < nvPairs.length; i++){
if(nvPairs[i]){
var nameValue = nvPairs[i].split(": ");
this._responseHeaders[nameValue[0]] = nameValue[1];
}
}
}
}
});
 
}
/trunk/api/js/dojo1.0/dojox/io/proxy/README
New file
0,0 → 1,82
-------------------------------------------------------------------------------
Project Name
-------------------------------------------------------------------------------
Version 0.5
Release date: MM/DD/YYYY (in progres, porting)
-------------------------------------------------------------------------------
Project state:
experimental
-------------------------------------------------------------------------------
Credits
James Burke (jburke@dojotoolkit.org)
-------------------------------------------------------------------------------
Project description
 
The XHR IFrame Proxy (xip) allows you to do cross-domain XMLHttpRequests (XHRs).
It works by using two iframes, one your domain (xip_client.html), one on the
other domain (xip_server.html). They use fragment IDs in the iframe URLs to pass
messages to each other. The xip.js file defines dojox.io.proxy.xip. This module
intercepts XHR calls made by the Dojo XHR methods (dojo.xhr* methods). The module
returns a facade object that acts like an XHR object. Once send is called on the
facade, the facade's data is serialized, given to xip_client.html. xip_client.html
then passes the serialized data to xip_server.html by changing xip_server.html's
URL fragment ID (the #xxxx part of an URL). xip_server.html deserializes the
message fragments, and does an XHR call, gets the response, and serializes the
data. The serialized data is then passed back to xip_client.html by changing
xip_client.html's fragment ID. Then the response is deserialized and used as
the response inside the facade XHR object that was created by dojox.io.proxy.xip.
-------------------------------------------------------------------------------
Dependencies:
 
xip.js: Dojo Core, dojox.data.dom
xip_client.html: none
xip_server.html: none (but see Additional Notes section)
-------------------------------------------------------------------------------
Documentation
 
There is some documentation that applies to the Dojo 0.4.x version of these files:
http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
 
The general theory still applies to this code, but the specifics are different
for the Dojo 0.9+ codebase. Doc updates hopefully after the basic code is ported.
 
The current implementation destroys the iframes used for a request after the request
completes. This seems to cause a memory leak, particularly in IE. So, it is not
suited for doing polling cross-domain requests.
-------------------------------------------------------------------------------
Installation instructions
 
Grab the following from the Dojox SVN Repository:
http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/proxy/xip.js
http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/proxy/xip_client.html
 
Install into the following directory structure:
/dojox/io/proxy/
 
...which should be at the same level as your Dojo checkout.
 
Grab the following from the Dojox SVN Repository:
http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/io/proxy/xip_server.html
 
and install it on the domain that you want to allow receiving cross-domain
requests. Be sure to read the documentation, the Additional Notes below, and
the in-file comments.
-------------------------------------------------------------------------------
Additional Notes
 
xip_client.html and xip_server.html do not work right away. You need to uncomment
out the script tags in the files. Additionally, xip_server.html requires a JS file,
isAllowed.js, to be defined. See the notes in xip_server.html for more informaiton.
 
XDOMAIN BUILD INSTRUCTIONS:
The dojox.io.proxy module requires some setup to use with an xdomain build.
The xip_client.html file has to be served from the same domain as your web page.
It cannot be served from the domain that has the xdomain build. Download xip_client.html
and install it on your server. Then set djConfig.xipClientUrl to the local path
of xip_client.html (just use a path, not a whole URL, since it will be on the same
domain as the page). The path to the file should be the path relative to the web
page that is using dojox.io.proxy.
 
 
 
 
/trunk/api/js/dojo1.0/dojox/io/proxy/xip_client.html
New file
0,0 → 1,267
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
<!-- Security protection: uncomment the start and end script tags to enable. -->
<!-- script type="text/javascript" -->
// <!--
/*
This file is really focused on just sending one message to the server, and
receiving one response. The code does not expect to be re-used for multiple messages.
This might be reworked later if performance indicates a need for it.
xip fragment identifier/hash values have the form:
#id:cmd:realEncodedMessage
 
id: some ID that should be unique among messages. No inherent meaning,
just something to make sure the hash value is unique so the message
receiver knows a new message is available.
cmd: command to the receiver. Valid values are:
- init: message used to init the frame. Sent as the first URL when loading
the page. Contains some config parameters.
- loaded: the remote frame is loaded. Only sent from server to client.
- ok: the message that this page sent was received OK. The next message may
now be sent.
- start: the start message of a block of messages (a complete message may
need to be segmented into many messages to get around the limitiations
of the size of an URL that a browser accepts.
- part: indicates this is a part of a message.
- end: the end message of a block of messages. The message can now be acted upon.
If the message is small enough that it doesn't need to be segmented, then
just one hash value message can be sent with "end" as the command.
To reassemble a segmented message, the realEncodedMessage parts just have to be concatenated
together.
*/
 
//MSIE has the lowest limit for URLs with fragment identifiers,
//at around 4K. Choosing a slightly smaller number for good measure.
xipUrlLimit = 4000;
xipIdCounter = 1;
 
function xipInit(){
xipStateId = "";
xipIsSending = false;
xipServerUrl = null;
xipStateId = null;
xipRequestData = null;
xipCurrentHash = "";
xipResponseMessage = "";
xipRequestParts = [];
xipPartIndex = 0;
xipServerWindow = null;
xipUseFrameRecursion = false;
}
xipInit();
function send(encodedData){
if(xipUseFrameRecursion == "true"){
var clientEndPoint = window.open(xipStateId + "_clientEndPoint");
clientEndPoint.send(encodedData);
}else{
if(!xipIsSending){
xipIsSending = true;
xipRequestData = encodedData || "";
 
//Get a handle to the server iframe.
xipServerWindow = frames[xipStateId + "_frame"];
if (!xipServerWindow){
xipServerWindow = document.getElementById(xipStateId + "_frame").contentWindow;
}
sendRequestStart();
}
}
}
 
//Modify the server URL if it is a local path and
//This is done for local/same domain testing.
function fixServerUrl(ifpServerUrl){
if(ifpServerUrl.indexOf("..") == 0){
var parts = ifpServerUrl.split("/");
ifpServerUrl = parts[parts.length - 1];
}
return ifpServerUrl;
}
function pollHash(){
//Can't use location.hash because at least Firefox does a decodeURIComponent on it.
var urlParts = window.location.href.split("#");
if(urlParts.length == 2){
var newHash = urlParts[1];
if(newHash != xipCurrentHash){
try{
messageReceived(newHash);
}catch(e){
//Make sure to not keep processing the error hash value.
xipCurrentHash = newHash;
throw e;
}
xipCurrentHash = newHash;
}
}
}
 
function messageReceived(encodedData){
var msg = unpackMessage(encodedData);
 
switch(msg.command){
case "loaded":
xipMasterFrame.dojox.io.proxy.xip.clientFrameLoaded(xipStateId);
break;
case "ok":
sendRequestPart();
break;
case "start":
xipResponseMessage = "";
xipResponseMessage += msg.message;
setServerUrl("ok");
break;
case "part":
xipResponseMessage += msg.message;
setServerUrl("ok");
break;
case "end":
setServerUrl("ok");
xipResponseMessage += msg.message;
xipMasterFrame.dojox.io.proxy.xip.receive(xipStateId, xipResponseMessage);
break;
}
}
function sendRequestStart(){
//Break the message into parts, if necessary.
xipRequestParts = [];
var reqData = xipRequestData;
var urlLength = xipServerUrl.length;
var partLength = xipUrlLimit - urlLength;
var reqIndex = 0;
 
while((reqData.length - reqIndex) + urlLength > xipUrlLimit){
var part = reqData.substring(reqIndex, reqIndex + partLength);
//Safari will do some extra hex escaping unless we keep the original hex
//escaping complete.
var percentIndex = part.lastIndexOf("%");
if(percentIndex == part.length - 1 || percentIndex == part.length - 2){
part = part.substring(0, percentIndex);
}
xipRequestParts.push(part);
reqIndex += part.length;
}
xipRequestParts.push(reqData.substring(reqIndex, reqData.length));
xipPartIndex = 0;
sendRequestPart();
}
function sendRequestPart(){
if(xipPartIndex < xipRequestParts.length){
//Get the message part.
var partData = xipRequestParts[xipPartIndex];
 
//Get the command.
var cmd = "part";
if(xipPartIndex + 1 == xipRequestParts.length){
cmd = "end";
}else if (xipPartIndex == 0){
cmd = "start";
}
setServerUrl(cmd, partData);
xipPartIndex++;
}
}
function setServerUrl(cmd, message){
var serverUrl = makeServerUrl(cmd, message);
 
//Safari won't let us replace across domains.
if(navigator.userAgent.indexOf("Safari") == -1){
xipServerWindow.location.replace(serverUrl);
}else{
xipServerWindow.location = serverUrl;
}
}
function makeServerUrl(cmd, message){
var serverUrl = xipServerUrl + "#" + (xipIdCounter++) + ":" + cmd;
if(message){
serverUrl += ":" + message;
}
return serverUrl;
}
 
function unpackMessage(encodedMessage){
var parts = encodedMessage.split(":");
var command = parts[1];
encodedMessage = parts[2] || "";
 
var config = null;
if(command == "init"){
var configParts = encodedMessage.split("&");
config = {};
for(var i = 0; i < configParts.length; i++){
var nameValue = configParts[i].split("=");
config[decodeURIComponent(nameValue[0])] = decodeURIComponent(nameValue[1]);
}
}
return {command: command, message: encodedMessage, config: config};
}
 
function onClientLoad(){
//Decode the init params
var config = unpackMessage(window.location.href.split("#")[1]).config;
 
xipStateId = config.id;
 
//Remove the query param for the IE7 recursive case.
xipServerUrl = fixServerUrl(config.server).replace(/(\?|\&)dojo\.fr\=1/, "");
//Make sure we don't have a javascript: url, just for good measure.
if(xipServerUrl.split(":")[0].match(/javascript/i)){
throw "Invalid server URL";
}
 
xipUseFrameRecursion = config["fr"];
if(xipUseFrameRecursion == "endpoint"){
xipMasterFrame = parent.parent;
}else{
xipMasterFrame = parent;
}
//Start counter to inspect hash value.
setInterval(pollHash, 10);
 
var clientUrl = window.location.href.split("#")[0];
var iframeNode = document.getElementsByTagName("iframe")[0];
iframeNode.id = xipStateId + "_frame";
iframeNode.src = makeServerUrl("init", 'id=' + xipStateId + '&client='
+ encodeURIComponent(clientUrl) + '&fr=' + xipUseFrameRecursion);
}
 
if(typeof(window.addEventListener) == "undefined"){
window.attachEvent("onload", onClientLoad);
}else{
window.addEventListener('load', onClientLoad, false);
}
// -->
<!-- </script> -->
</head>
<body>
<h4>The Dojo Toolkit -- xip_client.html</h4>
 
<p>This file is used for Dojo's XMLHttpRequest Iframe Proxy. This is the "client" file used
internally by dojox.io.proxy.xip.</p>
<iframe src="javascript:false"></iframe>
</body>
</html>
/trunk/api/js/dojo1.0/dojox/io/proxy/tests/xip.html
New file
0,0 → 1,62
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>XHR IFrame Proxy Tests</title>
<style type="text/css">
@import "../../../../dojo/resources/dojo.css";
@import "../../../../dijit/themes/tundra/tundra.css";
@import "../../../../dijit/themes/dijit.css";
</style>
 
<script type="text/javascript" src="../../../../dojo/dojo.js"
djConfig="isDebug:true"></script>
<script type="text/javascript" src="../xip.js"></script>
<script type="text/javascript">
dojo.require("dojox.io.proxy.xip");
 
function testXmlGet(){
/*
//Normal xhrGet call.
dojo.xhrGet({
url: "frag.xml",
handleAs: "xml",
load: function(result, ioArgs){
var foo = result.getElementsByTagName("foo").item(0);
 
dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
}
});
*/
 
//xip xhrGet call.
dojo.xhrGet({
iframeProxyUrl: "../xip_server.html",
url: "tests/frag.xml",
handleAs: "xml",
load: function(result, ioArgs){
var foo = result.getElementsByTagName("foo").item(0);
 
dojo.byId("xmlGetOut").innerHTML = "Success: First foobar value is: " + foo.firstChild.nodeValue;
}
});
 
}
 
dojo.addOnLoad(function(){
 
});
</script>
</head>
<body class="tundra">
 
<h1>XHR IFrame Proxy Tests</h1>
<p>Run this test from a web server, not from local disk.</p>
 
<p>
<button onclick="testXmlGet()">Test XML GET</button>
</p>
<div id="xmlGetOut"></div>
 
</body>
</html>
/trunk/api/js/dojo1.0/dojox/io/proxy/tests/frag.xml
New file
0,0 → 1,4
<response>
<foo>This is the foo text node value</foo>
<bar>This is the bar text node value</bar>
</response>