Hivext Community
Сентябрь 03, 2010, 05:19:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
Новости: Добро пожаловать в сообщество разработчиков Hivext.
 
Wiki   IDE   Console      Начало   Помощь Поиск Войти Регистрация  
Страниц: [1]
  Печать  
Автор Тема: Javascript - Кроссдоменые запросы к сервисам  (Прочитано 4950 раз)
Tenshi
Administrator
Jr. Member
*****

Авторитет: 1
Сообщений: 98



Просмотр профиля
« : Март 19, 2009, 05:01:43 »

Для подключения к Javascript коду можно воспользоваться готовыми клиентами: смотреть wiki http://hivext.ru/index.php/Подключение_сервисов#JavaScript.

Если готовые клиенты не нужны по каким то причинам, и требуется вызывать методы сервисов без них, то нужно ознакомится с реализацией ниже. Основная причина по которой создавались готовые клиенты это обеспечение кроссдоменного запроса, т.к. они запрещены с одного домена на другой, потребовалось специальное решение (работает в браузерах FF2+, IE6+, O9+ Safari3+, Chrome).

Итак пункты которые нужно выполнить чтобы вызвать метод сервиса через REST:

  • Делать HTTP (GET, POST) запросы на адреса нужных методов;
  • Кодировать входящие параметры (для GET в urlEncoding, для POST в multipart/form-data);
  • Декодировать JSON ответ метода в объект.

Для GET реализовано решение на основе Script Tag транспорта, для POST на основе Window Name транспорта.

Реализация класса для кроссдоменных запросов (можно использовать и в других проектах где требуются кроссдоменные вызовы):

Код
javascript:
 
var HttpRequest = {
 
//
// Метод get (базируется на script tag транспорте).
//
 
get : function(url, params, callback) {
var process = true,
sid = 'sid' + parseInt(Math.random()*1000000),
cb = 'cb=HttpRequest.callback.' + sid,
script = document.createElement('script');
script.type = 'text/javascript';
if(params) {
var sep = ''; url += "?";
for(var name in params) {
url += sep + name + '=' + params[name];
sep = '&';
}
}
if(url.indexOf('?') == -1) script.src = url + '?' + cb;
else if(url.match(/\?[\w\d]+/)) script.src = url + '&' + cb;
else script.src = url + cb;
HttpRequest.callback[sid] = function(response) {
process = false;
callback(response);
};
script.onerror = script.onload = script.onreadystatechange = function() {
if(!this.loaded && (!this.readyState
|| this.readyState == 'loaded'
|| this.readyState == 'complete'))
{
this.loaded = 1;
this.onerror = this.onload = this.onreadystatechange = null;
if(process) { callback(false); } else { /* Ответ пришел */ }
this.parentNode.removeChild(this);
delete script;
delete HttpRequest.callback[sid];
}
}
if(document.getElementsByTagName('head').length) {
document.getElementsByTagName('head')[0].appendChild(script);
} else { document.appendChild(script); }
},
 
//
// Метод post (базируется на window.name транспорте).
//
 
post : function(url, params, callback) {
function add2body(html) {
var b = document.body;
var div = document.createElement('div');        
div.innerHTML = html.join ? html.join('') : html;    
while (div.childNodes.length > 0) b.appendChild(div.childNodes[0]);
return b.lastChild;
}
var form, input, doc = document, fid = 'fid' + parseInt(Math.random()*1000000),
  html = '<iframe style="display:none" onload="HttpRequest._onLoad(this)"'
  + ' src="javascript:true" id="' + fid + '" name="' + fid + '"></iframe>';
var frame = add2body(html);            
HttpRequest.callback[fid] = callback;
if(params) {
if(params.nodeType) {
form = params;
} else {
form = document.createElement('form');
for(var name in params) {
var value = params[name];
input = document.createElement('input');
input.name = name;
input.value = value.replace(/\n/g, "");
form.appendChild(input);
}
}
if(form) {
form.method = 'post';
form.action = url;
form.target = fid;
form.acceptCharset = 'utf-8';
form.style.display = 'none';
document.body.appendChild(form);
form.submit();
form.parentNode.removeChild(form);
}
} else {
frame.src = url;
if(frame.contentWindow) {
frame.contentWindow.location.replace(url);
}
}
},
 
callback : {},
 
_getData : function(frame) {
if(frame.abort) return;
var callback = HttpRequest.callback[frame.id];
if(callback) {
try { callback(eval("(" + frame.contentWindow.name + ")")); } catch (ex) {}
delete HttpRequest.callback[frame.id];
}
setTimeout(function() { frame.parentNode.removeChild(frame); }, 0);
},
 
_onLoad : function(frame) {
var blank = 'about:blank',
wnd = frame.contentWindow;
try {    
        if (!frame.state && (wnd.location == blank
|| wnd.location == 'javascript:true')) return;
} catch (ex) {}
if(frame.state) {
return this._getData(frame);
} else wnd.location = blank;
frame.state = 1;
}
}

Примеры

Вызываем метод аутентификации Signin сервиса Authentication из пространства имен Users:

Код
javascript:
 
var url = 'http://api.hivext.ru/1.0/users/authentication/cross/signin';
var params = {
appid : '1234567890ABCDEF',
email : 'guest@guest.com',
password : 'guest'
};
HttpRequest.get(url, params, function(response) {
       alert(response.result); // Показать ответ метода.
});

Вызываем метод GetUserInfo сервиса Account из пространства имен Users:

Код
javascript:
 
var url = 'http://api.hivext.ru/1.0/users/account/cross/getuserinfo';
var params = {
appid : '1234567890ABCDEF',
session : '1234567890987654321'
};
HttpRequest.get(url, params, function(response) {
       alert(response.result); // Показать ответ метода.
});

Для post метода в качестве params также можно передавать готовый объект формы (form).
Вызываем метод Upload сервиса Uploader из пространства имен Storage:

Код
javascript:
 
var url = 'http://api.hivext.ru/1.0/storage/uploader/cross/upload';
var params = document.getElementById('form-upload-file');
HttpRequest.post(url, params, function(response) {
       alert(response.result); // Показать ответ метода.
});
« Последнее редактирование: Май 18, 2009, 05:26:36 от Tenshi » Записан
Страниц: [1]
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2008, Simple Machines LLC | Sitemap Valid XHTML 1.0! Valid CSS!