I'm trying to access an image protected by a simple http basic authentication mechanism. This example works fine when using my browser
...
var mImage = sap.m.Image("Im1");
mImage.setSrc("http://user:password#192.168.0.100/image.jpg");
...
var page = new sap.m.Page({
title: "Image",
content: mImage
}
Yet when I wrap it in a Cordova container (Android) this simple way of attaching user+pw does not seem to work. The webserver responds with a 401 error and my app does not send an authentication header.
The next step I've tried was to send a XmlHttRequest before trying to access time image URL:
var xhr =new XMLHttpRequest();
xhr.open("GET", "http://192.168.0.100/image.jpg", true, "user", "password");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert(xhr.responseText); //returns the image in text form i.e. authentication works fine
mImage.setSrc("http://192.168.0.100/image.jpg") //returns a 401
}
};
xhr.send(null);
Yet another failure. I was under the impression that once I am authenticated I will get a session. But apparently the xhr session and the sap.m.image session seem to be apart.
Any thoughts on how to tackle this issue
I found out that this appears to be a bug in the Android Webview. It is fixed in Android 5- This is fine for me and my example above works fine
Related
What I'm trying to achieve is basically something like android web view's shouldOverrideUrlLoading. I'm loading a specific URL into the web view which in turn have a series of redirects. The goal is to intercept the last URL and handle it by the application instead of the WebView component. It seems that something similar is available for the ios platform (onShouldStartLoadWithRequest) but didn't get to the android yet (https://github.com/facebook/react-native/pull/6478).
The workaround I've tried is to use onNavigationStateChange, parsing the URL and stopping the web view loading if needed:
onNavigationStateChange = (navState) => {
const url = new URL(navState.url);
const lastSegment = url.pathname.substr(url.pathname.lastIndexOf('/') + 1);
// Handle the get token ourselvs
if (lastSegment === GETTOKEN) {
this.refs[WEBVIEW_REF].stopLoading();
this.getToken()
}
this.setState({
url: navState.url,
backButtonEnabled: navState.canGoBack
});
}
The problem is that the stopLoading function is not really working in my case. I see that while executing the async function getToken() the browser continues the loading of the last URL.
Any suggestion would be appreciated.
I'm trying to POST data to an external URL in my AIR for Android app to log in users. It works in the Flash Debugger on my pc, but does not work on my Android device. I have the Internet Permission set for my app. I have listeners set up for IO_ERROR and SECURITY_ERROR but neither of these are fired. It just hangs there and does nothing when I test on the device, but it works fine in the debug player!?!?
EDIT: I've already searched for answers and the closest I came was this: AS3 AIR URLLoader POST which suggest specifying a content-type in my request, but that doesn't solve my issue
EDIT: It also works when I upload it to server and add a crossdomain.xml to the requested site.
public static function login(user:String, pass:String):void
{
username = user;
var request:URLRequest = new URLRequest( "http://mysite.com/"+user+"/login.json" );
request.method = URLRequestMethod.POST;
request.contentType = 'application/x-www-form-urlencoded';
var variables:URLVariables = new URLVariables();
variables.p = pass;
request.data = variables;
var requestor:URLLoader = new URLLoader();
requestor.addEventListener( Event.COMPLETE, loginRequestComplete );
requestor.addEventListener( IOErrorEvent.IO_ERROR, httpRequestError );
requestor.addEventListener( SecurityErrorEvent.SECURITY_ERROR, httpRequestError );
requestor.load( request );
}
Well, I finally managed to nail it....
I was grabbing my username and password from two textfields created in the ide.
The username textfield was set to multiline, which caused no problems in the online or debugger versions, but added a line break to the textfield on my android device, causing my api to return 400.
Changed it to a single line textfield and problem solved.
Crazy :)
While creating an Android app in Appcelerator's Titanium that involves both webView and background calls, I ran into a problem / bug where the cookies were getting corrupted on multiple createHTTPClient calls.
Cookies were originally obtained from the webView:
var webview = Ti.UI.createWebView();
webview.url = 'http://www.example.com';
window.add(webview);
webview.addEventListener('load', function(e) {
cookies = e.source.evalJS("document.cookie");
Titanium.App.Properties.setString('cookies',cookies);
}
window.open({modal:true});
and then later used with a background call:
var loader = Titanium.Network.createHTTPClient();
loader.open("GET",base_url + url);
loader.onload = function() {
// process response
}
loader.setRequestHeader('Cookie',Titanium.App.Properties.getString("cookies"));
loader.send();
The first time the above createHTTPClient chunk of code was called, everything worked, but subsequent runs of the above code would send corrupted cookies. In Google App Engine (gae), printing out the request headers would look like this (broken):
logging.info('Request:\n%s' % self.request)
broken response (only the cookie portion of the request header is shown)
Cookie: auth="eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357223709|4f622167f477a8c82cab196af4b0029af1a966d7", auth=eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357225569|7a469fab7a38a437649c25620729e07c4607f617
Cookie2: $Version=1
working response
Cookie: auth="eyJfdXNlciI6WzYsMSwiVmRoZEtnYWZRMnNxazFjaVM0U1lKdCIsMTM1NzIyMzcwOSwxMzU3MjIzNzA5XX0\075|1357223709|4f622167f477a8c82cab196af4b0029af1a966d7"
...
I suspect the issue has something to do with unicode characters or something inside createHTTPClient. Two auth= statements are shown in the corrupted cookie.
In summary, when the app first launches, the background Titanium.Network.createHTTPClient call works, and any calls after that appear to send corrupted cookies.
The HTTPClient documentation says "object is intended to be used for a single request," so I assumed everything would reset after multiple calls. But something was different after the first call.
Adding loader.clearCookies(base_url); to the code before setting the cookies seems to fix the issue.
var loader = Titanium.Network.createHTTPClient();
loader.open("GET",base_url + url);
loader.onload = function() {
// process response
}
loader.clearCookies(base_url); // THE FIX.
loader.setRequestHeader('Cookie',Titanium.App.Properties.getString("cookies"));
loader.send();
I can't seem to figure this one out, and I've tried googling that my fingers now hurt.
I am performing a HTTPClient request to my Domino Server that has SSL enabled. My request works perfectly when testing on iOS, but fails every time when testing through the Android Emulator and Mobile Web.
I'm running Android 2.2 SDK.
When I try to sign in from the App, I am definitely reaching the Server, because HTML is returned (the Login Web Form). When HTML is returned, it either means that the Authentication failed, or that the Redirect didn't work. When signing in through iOS the page redirects 100%.
Below is my code:
var orderReq = Titanium.Network.createHTTPClient();
var myurl = 'https://domain/db.nsf?login';
orderReq.setEnableKeepAlive;
orderReq.open('POST',myurl, false);
var params = {
username: "Joe Smith",
password: "Password",
redirectto: "path/db.nsf/response.xsp"
};
orderReq.send(params);
var myreturn = orderReq.responseText;
if((myreturn.charAt(0) === '<') || (myreturn === ""))
{
Ti.API.info('Fail');
return 'Fail';
}
else
{
Ti.API.info('Pass');
var json = orderReq.responseText;
var response = eval('(' + json + ')');
return response.username;
}
I have tried many properties and to no avail. I can confirm that the Android Emulator can connect to the Internet. It feels like either the Parameters are not being passed or the Redirect is not being triggered on the Web Page.
NOTE: I notice when authenticating through Android emulator that it fails immediately, where iOS returns true or false after 1-2 seconds.
Okay i know the question is too old. But, for anyone who is looking for an answer, this is what worked for me.
Make sure params is stringified before sending it to the server
orderReq.send(JSON.stringify(params));
Include the following right after the lines - orderReq.open('POST',myurl, false);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('charset','utf-8');
Currently trying to make an ajax post request to an IIS Express hosted MVC 4 Web API end point from an android VM (Bluestacks) on my machine. Here are the snippets of code that I am trying, and cannot get to work:
$.ajax({
type: "POST",
url: "http://10.0.2.2:28434/api/devices",
data: {'EncryptedPassword':'1234','UserName':'test','DeviceToken':'d234'}
}).always(function( data, textStatus, jqXHR ) {
alert( textStatus );
});
Whenever I run this request I always get back a textStatus of 'error'. After hours of trying different things, I pushed my End Point to an actual server, and was able to actually get responses back in PhoneGap if I built up an XMLHttpRequest by hand, like so:
var request = new XMLHttpRequest();
request.open("POST", "http://172.16.100.42/MobileRewards/api/devices", true);
request.onreadystatechange = function(){//Call a function when the state changes.
console.log("state = " + request.readyState);
console.log("status = " + request.status);
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
console.log("*" + request.responseText + "*");
}
}
}
request.send("{EncryptedPassword:1234,UserName:test,DeviceToken:d234}");
Unfortunately, if I try to use $.ajax() against the same end point in the snippet above I still get a status text that says 'error', here is that snippet for reference:
$.ajax({
type: "POST",
url: "http://172.16.100.42/MobileRewards/api/devices",
data: {'EncryptedPassword':'1234','UserName':'test','DeviceToken':'d234'}
}).always(function( data, textStatus, jqXHR ) {
alert( textStatus );
});
So really, there are a couple of questions here.
1) Why can't I get any ajax calls (post or get) to successfully hit my End Point when it's hosted via IIS Express on the same machine that the Android VM is running?
2) When my end point is hosted on an actual server, through IIS and served through port 80, why can't I get post requests to be successful when I use jquery's ajax calls? (Even though I can get it to work by manually creating an XMLHttpRequest)
Thanks
Are you sure that BlueStacks uses the same host IP (10.0.2.2) as the emulator? I'm not familiar with it so I'm not sure what the answer to that is.
jQuery wants the data to be a string, try:
data: JSON.stringify({'EncryptedPassword':'1234','UserName':'test','DeviceToken':'d234'});
and for good measure, add
contentType: 'application/json',
in your ajax settings.
To anyone who ever looks this up, the issue ended up being the port that IIS Express was using on my local machine. When I got things to route through port 80, everything worked okay.