Nie referery nie są potrzebne w HiLink API. Przynajmniej nie zauważyłem ich potrzeby. W pierwotnym opisie jaki zrobiłem bazując na opisie Chaddy'ego były wykorzystywane refy w np w SMSach, ale jak przeglądnąłem JS i sprawdziłem u siebie okazało się, że nie trzeba ich stosować.
Niestety nie mam modemu który używa nowszego oprogramowania (chodzi o firmware, a nie WebUI), więc nie sprawdzę co jest problemem.
Zresztą poniżej masz kod JS z API WebUI w wersji 17 pobierający dane:
Kod: Zaznacz cały
// urlstr : URL of the Restful interface.
// callback_func : Callback function to handle response, this callback function
// have one parameter
// callback_func($xml) - $xml : a jQuery XML object which is successfully get
// from getAjaxData.
// options.sync
// options.timout
// options.errorCB
function getAjaxData(urlstr, callback_func, options) {
var myurl = AJAX_HEADER + urlstr + AJAX_TAIL;
var isAsync = true;
var nTimeout = AJAX_TIMEOUT;
var errorCallback = null;
if (options) {
if (options.sync) {
isAsync = (options.sync == true) ? false : true;
}
if (options.timeout) {
nTimeout = parseInt(options.timeout, 10);
if (isNaN(nTimeout)) {
nTimeout = AJAX_TIMEOUT;
}
}
errorCallback = options.errorCB;
}
var headers = {};
if(!($.isArray(g_requestVerificationToken))) {
headers['__RequestVerificationToken'] = g_requestVerificationToken;
}
$.ajax({
async: isAsync,
headers: headers,
//cache: false,
type: 'GET',
timeout: nTimeout,
url: myurl,
//dataType: ($.browser.msie) ? "text" : "xml",
error: function(XMLHttpRequest, textStatus) {
try {
if (jQuery.isFunction(errorCallback)) {
errorCallback(XMLHttpRequest, textStatus);
}
log.error('MAIN : getAjaxData(' + myurl + ') error.');
log.error('MAIN : XMLHttpRequest.readyState = ' + XMLHttpRequest.readyState);
log.error('MAIN : XMLHttpRequest.status = ' + XMLHttpRequest.status);
log.error('MAIN : textStatus ' + textStatus);
} catch (exception) {
log.error(exception);
}
},
success: function(data) {
log.debug('MAIN : getAjaxData(' + myurl + ') sucess.');
log.trace(data);
var xml;
if (typeof data == 'string' || typeof data == 'number') {
if((-1 != this.url.indexOf('/api/ussd/get') )&&( -1 != data.indexOf("content"))) {
data = smsContentDeleteWrongChar(data);
}
if (!window.ActiveXObject) {
var parser = new DOMParser();
xml = parser.parseFromString(data, 'text/xml');
} else {
//IE
xml = new ActiveXObject('Microsoft.XMLDOM');
xml.async = false;
xml.loadXML(data);
}
} else {
xml = data;
}
var ret = xml2object($(xml));
if('error' == ret.type) {
if(ERROR_WRONG_SESSION_TOKEN == ret.error.code) {
log.error('Main: getajax'+ this.url +'session token error');
gotoPageWithoutHistory(HOME_PAGE_URL);
return;
}
if(ERROR_WRONG_SESSION == ret.error.code) {
log.error('Main: getajax'+ this.url +'session error');
gotoPageWithoutHistory(HOME_PAGE_URL);
return;
}
}
if('error' == ret.type && ERROR_WRONG_TOKEN == ret.error.code) {
getAjaxToken();
getAjaxData(urlstr, callback_func, options);
} else if (typeof callback_func == 'function') {
callback_func($(xml));
} else {
log.error('callback_func is undefined or not a function');
}
}
});
}
I zapisujace dane:
Kod: Zaznacz cały
// urlstr : URL of the Restful interface.
// xml: xml string to be submit to server.
// callback_func : Callback function to handle response, this callback function
// have one parameter
// callback_func($xml) - $xml : a jQuery XML object which is successfully get
// from getAjaxData.
// options.sync
// options.timout
// options.errorCB
function saveAjaxData(urlstr, xmlDate, callback_func, options) {
var myurl = AJAX_HEADER + urlstr + AJAX_TAIL;
var isAsync = true;
var nTimeout = AJAX_TIMEOUT;
var errorCallback = null;
if (options) {
if (options.sync) {
isAsync = (options.sync == true) ? false : true;
}
if (options.timeout) {
nTimeout = parseInt(options.timeout, 10);
if (isNaN(nTimeout)) {
nTimeout = AJAX_TIMEOUT;
}
}
errorCallback = options.errorCB;
}
var headers = {};
if($.isArray(g_requestVerificationToken)) {
if(g_requestVerificationToken.length > 0) {
headers['__RequestVerificationToken'] = g_requestVerificationToken[0];
g_requestVerificationToken.splice(0, 1);
} else {
setTimeout( function () {
saveAjaxData(urlstr, xmlDate, callback_func, options);
}, 50);
return;
}
} else {
headers['__RequestVerificationToken'] = g_requestVerificationToken;
}
$.ajax({
async: isAsync,
headers: headers,
//cache: false,
type: 'POST',
timeout: nTimeout,
url: myurl,
// dataType: ($.browser.msie) ? "text" : "xml",
data: xmlDate,
error: function(XMLHttpRequest, textStatus) {
try {
if("12030" == XMLHttpRequest.status || "12031" == XMLHttpRequest.status || "12019" == XMLHttpRequest.status || "400" == XMLHttpRequest.status) {
saveAjaxData(urlstr, xmlDate, callback_func, options);
return;
} else if(jQuery.isFunction(errorCallback)) {
errorCallback(XMLHttpRequest, textStatus);
}
log.error('MAIN : saveAjaxData(' + myurl + ') error.');
log.error('MAIN : XMLHttpRequest.readyState = ' + XMLHttpRequest.readyState);
log.error('MAIN : XMLHttpRequest.status = ' + XMLHttpRequest.status);
log.error('MAIN : textStatus' + textStatus);
} catch (exception) {
log.error(exception);
}
},
success: function(data) {
log.debug('MAIN : saveAjaxData(' + myurl + ') success.');
log.trace(data);
var xml;
if (typeof data == 'string') {
if (-1 != this.url.indexOf('/api/sms/sms-list') && -1 != data.indexOf('Messages')) {
data = smsContentDeleteWrongChar(data);
}
if (!window.ActiveXObject) {
var parser = new DOMParser();
xml = parser.parseFromString(data, 'text/xml');
} else {
//IE
xml = new ActiveXObject('Microsoft.XMLDOM');
xml.async = false;
xml.loadXML(data);
}
} else {
xml = data;
}
var xml_ret = xml2object($(xml));
if(typeof xml_ret.error != 'undefined' && -1 == this.url.indexOf('/api/user/session')) {
if(xml_ret.error.code == ERROR_SYSTEM_NO_RIGHTS && current_href != "home") {
gotoPageWithoutHistory(HOME_PAGE_URL);
return;
}
if(ERROR_VOICE_BUSY == xml_ret.error.code) {
gotoPageWithoutHistory(VOICE_BUSY_URL);
return;
}
if(ERROR_WRONG_TOKEN == xml_ret.error.code) {
getAjaxToken();
saveAjaxData(urlstr, xmlDate, callback_func, options);
return;
}
if(ERROR_WRONG_SESSION_TOKEN == xml_ret.error.code) {
log.error('Main: saveAjaxDate'+ this.url +'session token error');
gotoPageWithoutHistory(HOME_PAGE_URL);
return;
}
if(ERROR_WRONG_SESSION == xml_ret.error.code) {
log.error('Main: saveAjaxDate'+ this.url +'session error');
gotoPageWithoutHistory(HOME_PAGE_URL);
return;
}
} else if(isAjaxReturnOK(xml_ret) && -1 != this.url.indexOf('/api/user/login')) {
log.debug('Main: login success, empty token list');
if($.isArray(g_requestVerificationToken)) {
g_requestVerificationToken = [];
}
}
if (typeof callback_func == 'function') {
callback_func($(xml));
} else {
log.error('callback_func is undefined or not a function');
}
},
complete: function(XMLHttpRequest, textStatus) {
var headers = XMLHttpRequest.getAllResponseHeaders();
if(headers.indexOf('__RequestVerificationTokenone') > 0) {
g_requestVerificationToken.push(getTokenFromHeader(headers, '__RequestVerificationTokenone'));
if(headers.indexOf('__RequestVerificationTokentwo') > 0) {
g_requestVerificationToken.push(getTokenFromHeader(headers, '__RequestVerificationTokentwo'));
}
} else if(headers.indexOf('__requestverificationtokenone') > 0) {
g_requestVerificationToken.push(getTokenFromHeader(headers, '__requestverificationtokenone'));
if(headers.indexOf('__requestverificationtokentwo') > 0) {
g_requestVerificationToken.push(getTokenFromHeader(headers, '__requestverificationtokentwo'));
}
} else if(headers.indexOf('__RequestVerificationToken') > 0) {
g_requestVerificationToken.push(getTokenFromHeader(headers, '__RequestVerificationToken'));
} else if(headers.indexOf('__requestverificationtoken') > 0) {
g_requestVerificationToken.push(getTokenFromHeader(headers, '__requestverificationtoken'));
} else {
log.error('MAIN: saveAjaxData can not get response token');
}
}
});
}
Pobranie tokena to odwołanie się do funkcji Get z odpowiednim adresem API:
Kod: Zaznacz cały
function getAjaxToken() {
var meta = $("meta[name=csrf_token]");
var i = 0;
if(meta.length > 0) {
g_requestVerificationToken = [];
for(i; i < meta.length; i++) {
g_requestVerificationToken.push(meta[i].content);
}
} else {
getAjaxData('api/webserver/token', function($xml) {
var ret = xml2object($xml);
if ('response' == ret.type) {
g_requestVerificationToken = ret.response.token;
}
}, {
sync: true
});
}
}
A tu przykładowo jedna z mniejszych funkcji czyli switch_mode przełączająca modem w tryb debug/project:
Kod: Zaznacz cały
function switch_mode(value)
{
var request = {
mode: value
};
var xmlstr = object2xml("request", request);
saveAjaxData("api/device/mode", xmlstr, function($xml){
var ret = xml2object($xml);
if (isAjaxReturnOK(ret))
{
closeWindow();
}
});
}
Ja tu nigdzie nie widzę potrzeby referera, ale mogę się mylić tym bardziej, że nie zagłębiałem się w dokumentację jquery.
CGI jest zaimplementowane, ale da się wykorzystać tylko jedną funkcję switch_mode, gdzie wykorzystywana jest powyższa funkcja Send, która jak widać sama troszczy się o token.