I want to access to the service web via my PhoneGap/android application with xmlhttprequest, but the code below returns "Status is 401".
var request = new XMLHttpRequest();
request.open("GET","http://www.mysite.fr/api/customers/2",true);
request.onreadystatechange = function() {
alert("Status is "+request.status);
if (request.status == 200 || request.status == 0){
response = request.responseXML.documentElement;
itemDescription = response.getElementsByTagName('lastname')[0].firstChild.data;
alert ( itemDescription );
}
}
request.send();
Can anyone help me explaining the error or offering me a solution?
if your website is created by prestashop, so to access the webservice using Xmlhttprequest, the request.open should be like this:
request.open("GET","http://www.mysite.fr/api/customes/2?PHP_AUTH_USER="+PHP_AUTH_USER+"&ws_key="+ws_key,true);
with: PHP_AUTH_USER="" and ws_ke=key_generated_by_the_webservice
Related
I have a question like the one is asked here in this link: Solution: Run game local (file:///) Construct 2
I did the third step of the solution. I added
self.loadProject(FULL_CONTENT_INSIDE_MY_DATA.JS); return;
just after
xhr.open("GET", datajs_filename, true);
var supportsJsonResponse = false;
in c2runtime.js. But when I test the game in my Android App, I only see the first page of construct; The game cannot be loaded and the first page of construct remains as an image.
A piece of my code:
Runtime.prototype.requestProjectData = function ()
{
var self = this;
var xhr;
if (this.isWindowsPhone8)
xhr = new ActiveXObject("Microsoft.XMLHTTP");
else
xhr = new XMLHttpRequest();
var datajs_filename = "data.js";
if (this.isWindows8App || this.isWindowsPhone8 || this.isWindowsPhone81 || this.isWindows10)
datajs_filename = "data.json";
//xhr.open("GET", datajs_filename, true); <-- I commented this line
var supportsJsonResponse = false;
self.loadProject(FULL_CONTENT_INSIDE_MY_DATA.JS); return;
Just run it through a localhost server
use Wamp or Xampp
In my ionic app I have a POST request to do login. This works fine on an iPhone but when I test the app on an Android phone the server returns a 404 Not Found error.
My code for making the HTTP request looks like this:
loginUser: function(email,password) {
var em = email.replace(/\s/g,'');
var pw = password.replace(/\s/g,'');
var url = apiDomain + '/api/v1/user/login/';
if (em && pw) {
return $http.post(url, {
auth: {
email: em,
password: pw
}
}).then(function successCallback(response) {
alert('login success. response = '+JSON.stringify(response));
return response;
}, function errorCallback(response) {
alert('login fail. response = '+JSON.stringify(response));
return -1;
});
}
},
Can anyone think of a reason why this would work on an iPhone but not on an Android phone?
The text shown by the alert() in the errorCallback is:
login fail. response = {
"data":"",
"status":404,
"config":{
"method":"POST",
"transformRequest":[null],
"url":"http://cues-server-dev.elasticbeanstalk.com/api/v1/user/login/",
"data":{
"auth":"{
"email":"aa#aa.aa",
"password":"alcohol"}},
"headers":{
"Accept":"application/json,text,plain,*/*",
"Content-Type":"application/json;charset=utf-8"}},
"statusText":"Not Found"}
I am at a loss to understand why this works on an iPhone but not an Android phone.
It may be to do with the URL prefix. Have you tried using:
apiDomain = #"https://cues-server-dev.elasticbeanstalk.com"
or
apiDomain = #"http://www.cues-server-dev.elasticbeanstalk.com"
or some other variant.
I'm trying to find the best way to send my users a real-time status update of a process that's running on my server - this process is broken up into five parts. Right now I'm just 'pulling' the status using an Ajax call every few seconds to a PHP file that connects to MySQL and reads the status, but as you can imagine, this is extremely hard on my database and doesn't work so well with users that don't have a strong internet connection.
So I'm looking for a solution that will 'push' data to my client. I have APE push-engine running on my server now, but I'm guessing Socket.IO is better for this? What if they're on 3G and they miss a status update?
Thanks in advance :)
I guess my answer may match what you need.
1st: You Have to Get Node.js to run the socket.io
BELOW IS SAMPLE CODE FOR SERVER:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8800); //<---------Port Number
//If No Connection / Page Error
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
//If there is connection
io.sockets.on('connection', function (socket) {
//Set Varible
var UserID;
var Old_FieldContent = "";
socket.on('userid', function (data) {
if(data.id){
UserID = data.id;
StartGetting_FileName(UserID)
}
});
//Checking New Status
function StartGetting_FileName(UserID){
//Create Interval for continues checking from MYSQL database
var myInterval = setInterval(function() {
//clearInterval(myInterval);
//MySQL Connection
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : '3306',
user : 'root',
password : 'ABCD1234',
database : 'test',
});
//Setup SQL Query
var SQL_Query = "SELECT FileName FROM status WHERE UserID = '"+UserID+"'";
connection.connect();
connection.query(SQL_Query, function(err, rows, fields) {
//Do if old result is, different with new result.
if(Old_FieldContent !== rows[0].FileName){
if (err) throw err;
//Display at Server Console
console.log('------------------------------------------');
console.log('');
console.log('Fields: ', fields[0].name);
console.log('Result: ', rows[0].FileName);
console.log('');
console.log('------------------------------------------');
//Send Data To Client
socket.emit('news', { FieldName: fields[0].name });
socket.emit('news', { FieldContent: rows[0].FileName });
//Reset Old Data Variable
Old_FieldContent = rows[0].FileName;
}
});
connection.end();
}, 500 );
}
});
BELOW IS CLIENT HTML & JS:
<!doctype html>
<html>
<head>
<title>web sockets</title>
<meta charset="utf-8">
<!-- URL PATH TO LOAD socket.io script -->
<script src="http://15.17.100.165:8800/socket.io/socket.io.js"></script>
<script>
//Set Variable
var UserID = "U00001";
var socket = io.connect('http://15.17.100.165:8800');
var Field_Name = "No Data";
var Field_Content = "No Data";
// Add a disconnect listener
socket.on('connecting',function() {
msgArea.innerHTML ='Connecting to client...';
console.log('Connecting to client...');
//Once Connected Send UserID to server
//for checking data inside MYSQL
socket.emit('userid', { id: UserID });
});
// Get data that push from server
socket.on('news', function (data) {
console.log(data);
writeMessage(data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
msgArea.innerHTML ='The client has disconnected!';
console.log('The client has disconnected!');
});
//Function to display message on webpage
function writeMessage(msg) {
var msgArea = document.getElementById("msgArea");
if (typeof msg == "object") {
// msgArea.innerHTML = msg.hello;
if(msg.FieldName !== undefined){
Field_Name = msg.FieldName;
}
if(msg.FieldContent !== undefined){
Field_Content = msg.FieldContent;
}
}else {
msgArea.innerHTML = msg;
}
msgArea.innerHTML = Field_Name +" = "+ Field_Content;
}
</script>
</head>
<body>
<div id="msgArea">
</div>
</body>
</html>
You should consider using push notifications, with the service provided for Android by Google as C2DM: https://developers.google.com/android/c2dm/
You will need to implement a PhoneGap plugin to handle the native notifications, and communicate them to your PhoneGap project that will then (and only then) query your server .
As K-ballo above points out, using a push notification plugin would be best.
Luckily, some good citizen on GitHub has done this already!
https://github.com/awysocki/C2DM-PhoneGap
Please note: the above C2DM plugin was built for PhoneGap v1.2, so if you are running a more up-to-date version you will have to tweak the native code a bit to get it working better.
I have a really weird scenario that I'm stuck on. I have a ASP.Net MVC 4 app where I'm authenticating a user and creating an authCookie and adding it to the response's cookies then redirecting them to the target page:
if (ModelState.IsValid)
{
var userAuthenticated = UserInfo.AuthenticateUser(model.UserName, model.Password);
if (userAuthenticated)
{
var userInfo = UserInfo.FindByUserName(model.UserName);
//SERIALIZE AUTHENTICATED USER
var serializer = new JavaScriptSerializer();
var serializedUser = serializer.Serialize(userInfo);
var ticket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, DateTime.Now.AddMinutes(30), false, serializedUser);
var hash = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash) {Expires = ticket.Expiration};
Response.Cookies.Add(authCookie);
if (Url.IsLocalUrl(model.ReturnUrl) && model.ReturnUrl.Length > 1 && model.ReturnUrl.StartsWith("/") && !model.ReturnUrl.StartsWith("//") && !model.ReturnUrl.StartsWith("/\\"))
{
return Redirect(model.ReturnUrl);
}
var url = Url.Action("Index", "Course");
return Redirect(url);
}
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
This is working just fine in all browsers. I can login and access the secure pages in my app.
My client is requesting an android version of this app. So, I'm trying to figure out how to convert this app into an APK file. My first attempt is to create a simple index.html page with an iframe that targets the application. This works just fine in Firefox and IE 9. However, when accessing the index.html page that contains the iframe that points to the app via Chrome, I get past the login code above and the user gets redirected to the secure controller, but the secure controller has a custom attribute to make sure the user is authenticated:
public class RequiresAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated) return;
if (filterContext.HttpContext.Request.Url == null) return;
var returnUrl = filterContext.HttpContext.Request.Url.AbsolutePath;
if (!filterContext.HttpContext.Request.Browser.IsMobileDevice)
{
filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl + string.Format("?ReturnUrl={0}", returnUrl), true);
}
else
{
filterContext.HttpContext.Response.Redirect("/Home/Home", true);
}
}
}
My app is failing on: filterContext.HttpContext.User.Identity.IsAuthenticated. IsAuthenticated is always false, even though the user was authenticated in the code above.
Keep in mind this only happens when accessing the app via iframe in Chrome. If I access the app directly instead of via iframe, then everything works just fine.
Any ideas?
UPDATE:
My controller extends SecureController. In the constructor of SecureController I have the code that deserializes the user:
public SecureController()
{
var context = new HttpContextWrapper(System.Web.HttpContext.Current);
if (context.Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
var serializer = new JavaScriptSerializer();
var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
var ticket = FormsAuthentication.Decrypt(cookie);
CurrentUser = serializer.Deserialize<UserInfo>(ticket.UserData);
}
else
{
CurrentUser = new UserInfo();
}
//if ajax request and session has expired, then force re-login
if (context.Request.IsAjaxRequest() && context.Request.IsAuthenticated == false)
{
context.Response.Clear();
context.Response.StatusCode = 401;
context.Response.Flush();
}
}
First, you should be deriving from AuthorizeAttribute, not an ActionFilterAttribute. Authorization attributes execute before the method is even called at a higher level of the pipeline, while ActionFilters execute much further down, and other attributes can execute before yours.
Secondly, you aren't showing the code you use to decrypt the ticket and set the IPrincipal and IIdentity. Since that's where the problem is, it's odd that you didn't include it.
i am trying to do login application which takes id and password..when i click on logi button then it will connect to our local server by JSON..with the specified URL..the code is..
var loginReq = Titanium.Network.createHTTPClient();
loginReq.onload = function()
{
var json = this.responseText; alert(json);
var response = JSON.parse(json);
if (response.data.status == "success")
{ alert("Welcome ");
}
else
{ alert(response.data.status);
}
};
loginReq.onerror = function(event)
{
alert(event.toSource());
//alert("Network error");
};
loginBtn.addEventListener('click',function(e)
{ if (username.value != '' && password.value != '')
{
var url = 'our local url action=login&id='+username.value+'&pwd='+password.value;
loginReq.open("POST",url);
loginReq.send();
}
else
{
alert("Username/Password are required");
}
});
Here it is not connecting our URl..so it is entering into loginReq.onerror function...instead of loginReq.onload function..why it is throwing run time error.. The same code working fine with Iphone..
The Run Time Error is..
TypeError:Cannot call property toSource in object{'source':[Ti.Network.HttpClient],specified url} is not a function,it is a object.
This is wat the error..please let me Know...
Apparently the toSource() function does not exist in android, as it is an object. Try debugging and see what the object event contains.
You could do that by adding a line above the alert line, and adding a debug line to it.
Look in debug mode and see all variables
"toSource()" is not a documented function for either platform, and I also do not see it in the source for Titanium Mobile. If you aren't getting the error on iOS, I'm guessing it is because the error handler isn't getting called. Perhaps your emulator or device does not have internet access, whereas your iOS simulator or device does?
Regardless, error handling in the HTTPClient normally looks something like this:
loginReq.onerror = function(e)
{
Ti.API.info("ERROR " + e.error);
alert(e.error);
};