Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

WP8 xhr problem #4288

Closed
wideblue opened this issue Oct 5, 2013 · 37 comments
Closed

WP8 xhr problem #4288

wideblue opened this issue Oct 5, 2013 · 37 comments

Comments

@wideblue
Copy link

wideblue commented Oct 5, 2013

Ruing basic angular app (generated with yeoman angular generator) in Cordova Windows Phone 8 produces following error in weinre, the Visual Studio doesn't give any good indication why app is not running.

Error: Access is denied.
at hookedFunction (http://"my-weinre-ip":8080/target/target-script-min.js#ddtest:551:1)
at Anonymous function (x-wmapp0://www/components/angular/angular.js:9457:7)
at sendReq (x-wmapp0://www/components/angular/angular.js:9334:9)
at $http (x-wmapp0://www/components/angular/angular.js:9125:7)
at Anonymous function (x-wmapp0://www/components/angular/angular.js:9268:11)
at Anonymous function (x-wmapp0://www/components/angular/angular.js:7592:17)
at wrappedCallback (x-wmapp0://www/components/angular/angular.js:6996:15)
at wrappedCallback (x-wmapp0://www/components/angular/angular.js:6996:15)
at Anonymous function (x-wmapp0://www/components/angular/angular.js:7033:11)
at $eval (x-wmapp0://www/components/angular/angular.js:8219:9)

the Fixed #2303 was adapted and applied to angular-1.0.8 before running the app

I also applied Fixed #3103 but it doesn't affect the error massage.

Used:
angular:1.0.8
Cordova: 2.9.0

@wideblue
Copy link
Author

wideblue commented Oct 7, 2013

Error: Access is denied happens on this line in angular.js
xhr.open(method, url, true);

when a view (main.html) tries to get loaded.
I found this thread dealing with what it seems very similar problem
https://groups.google.com/forum/#!topic/phonegap/p29CZUdMWz4

trying to follow suggestions from the tread I manually bootstrapped angular after cordova devicesready event has fired, but I'm still catching Access is denied error. I also tried changing templateUrl in $routeProvider from

templateUrl: 'views/main.html';
to
templateUrl: 'www/views/main.html';
to

templateUrl: '/www/views/main.html';
with no success.

@wideblue
Copy link
Author

wideblue commented Oct 7, 2013

Also this

xhr.open('GET', "x-wmapp0://www/" + url, true);
as suggested here
requirejs/require-cs#48
is not working for me

@wideblue
Copy link
Author

wideblue commented Oct 7, 2013

I have managed to get the app runing by including jquery (2.0.3) and changing line of code above xhr.open(method, url, true);
from
var xhr = new XHR();
to
var xhr = new XMLHttpRequest();

this is more a workaround than a solution
EDIT :
I spoke too quickly the above solution works on WP7 but unfortuanately not on WP8, where I get this error
http://stackoverflow.com/questions/18825945/phonegap-and-windows-phone-7-indexoutofboundsexception/18851913#18851913

I haven't figured out how to prepare xhr request to work on WP8 yet.

@mchambaud
Copy link

I'm having the same problem on WP8.

@wideblue
Copy link
Author

Switching to Cordova 3.1.0 was an improvement and I managed to make the app working on WP8

@manuelnelson
Copy link

I upgraded to 3.1 and am using WP8 but haven't been able to get this to work with angular. Did you have to do any of the above workarounds to get it to work?

@wideblue
Copy link
Author

I did all the things I mentioned but I haven't checked if they are all necessary.

I applied two patches from #3103 (manually), plus the change that I made, plus included jquery (2.0.3) before angular.

@mchambaud
Copy link

It was an issue with inconsistent use of HTTPS for me.

@regou
Copy link

regou commented Nov 2, 2013

Same here,I tried everything I found but not working,waiting for some good news

@naz
Copy link

naz commented Nov 13, 2013

Can anybody post at least some more complex working code? I am having the same trouble here on phonegap 3.1.0 WP8.

@mchambaud
Copy link

Gargol, are you using HTTPS? In my case, I got this error because not all static files were loaded securely.

@Robert-W
Copy link

I had this same issue and made a very simple app to test routing and was able to finally get it working after countless attempts, i used the following:
In angular.js change:

var xhr = new XHR();
to
var xhr = new XMLHttpRequest();

In your html, I set mine up as follows:
<script src="app/libs/jquery-2.0.3.min.js"></script>
<script>jQuery.isUnsafe = true;</script>
<!-- Angular Version 1.2.0 -->
<script src="app/libs/angular.js"></script>
<script src="app/libs/angular-route.js"></script>
<script src="app/js/app.js"></script>
<script src="app/js/controllers.js"></script>

And then I had to whitelist my urls in app.js as angular's function was treating my partials as untrusted, it was giving issues with this

templateUrl = $sce.getTrustedResourceUrl(templateUrl);

So my app.js looks like the following with some code to whitelist all my url's, note this could be potentially dangerous whitelisting everything so this is probably best used for dev but you can easily find some info on whitelisting specific url's in angular's website here

var module = angular.module("simpleApp",['ngRoute','appControllers','projectControllers']).
    config(["$routeProvider",function($routeProvider){
        $routeProvider.
            when("/home",{templateUrl:'app/partials/home.html',controller: 'homeController'}).
            when("/project1",{templateUrl:'app/partials/project1.html',controller: 'project1Controller' }).
            when("/project2",{templateUrl:'app/partials/project2.html',controller: 'project2Controller' }).
            otherwise({redirectTo: "/home"});
}],function($sceDelegateProvider){
    $sceDelegateProvider.resourceUrlWhitelist(['.*']);
});

If people want full source code let me know and I will upload it to github, I just got this working maybe 20 minutes ago at the office so after I get home I can upload

This was using 2.9.1 template in Visual Studio, and then using cordova 3.2.0-rc.1 to create the project from the command line and copying the code in www over to the template

@sureshvsvb
Copy link

Hi Robert-W,

I am trying to build a windows 8 APP with AngularJS. Routing seems to me not working out. I am using VS 2013 and creating a metro app using javascript and html.

I have tried your suggestion but it did not worked out for me. I used Jquery specific to W8.

Please share the above working code, so i can check and try it out.

Thanks,
Suresh

@Robert-W
Copy link

Hi Suresh,

I have uploaded the code here: https://github.com/Robert-W/Angular-Win8

This is just the HTML and JavaScript Code, all the changes mentioned in my above post are included in this code so you won't have to add jQuery or angular yourself or change the XHR to XMLHttpRequest, that's all done.

I included in the repo my cordova.js and cordova-plugins.js that was auto generated by the cordova command line tool, these are from version 3.2.0-rc1 so make sure to use these and not older ones, I was not able to get this work with earlier versions of cordova.

Also Very IMPORTANT, I tested this earlier today with the PhoneGap 2.9.0 template in visual studio and a much larger project then the one I posted at the above url and could not get it to work, then I remembered I had the 2.9.1 template, copied all the code from the www directory and it immediately worked.

Also, in index.html, you'll see some code commented out, uncomment the script tag for cordova.js and also uncomment the code in window.onload, you will need to bootstrap the app after device ready fires, I have read this is also required but have not yet tested without it so to be safe, I would do it this way

@sureshvsvb
Copy link

Hi Robert,

When i try to use the same files ( jquery, angular.js and angular-route.js) i am getting unsafe content error. So i am using jQuery specific to Windows 8 file.

Any other suggestion to implement angular routing on windows 8 ?

How can i run your solution ?

Regards,
Suresh

@wideblue
Copy link
Author

This issue is about running an app on Windows Phone 8. Running an app on Windows 8 has different problems, a good explanation about that can be found here
http://blog.kadople.com/2013/06/getting-started-with-angularjs-in.html

@sureshvsvb
Copy link

I am able to run the application Windows 8. However my issue is on getting Angular routing to work and load templates.

@Robert-W
Copy link

Are you using Windows Phone 8 or Windows 8 Desktop, this solution was tested on Windows Phone 8 not Windows 8 desktop.

Also are you using the Cordova files I provided and PhoneGaps 2.9.1 template(you will need to download this from phonegap), these are very important, older template did not work.

One thing to try is to search the angular-route.js and look for $sceDelegateProvider.getTrustedResourceUrl inside the when function, and do some debugging around this, make sure it is getting the correct templateUrl for your partial and then look at the $http.get call that immediately follows and alert the response.data, you should see your partial HTML code here.

If this is for desktop checkout the link posted by wideblue because as I mentioned, this has only been tested on WP8.

@sureshvsvb
Copy link

Thanks Robert-W. I am running the solution on Windows 8 desktop

I have used the windows 8 version of jQuery. I could debug and see the template is loaded properly.

In angular-route.js,
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
if (angular.isDefined(templateUrl)) {
next.loadedTemplateUrl = templateUrl;
template = $http.get(templateUrl, {cache: $templateCache}).
then(function (response) {
return response.data;
});

However, i don't see it on the UI.

I have copied the sample project here on GitHub

https://github.com/sureshvsvb/AngularRoutingWindows8/tree/master/helloWorldAngularApp

Regards,
Suresh

@Robert-W
Copy link

I am not sure if this will work on Windows 8 Desktop. PhoneGap does some behinds the scene voodoo with their template to help make this work which is why I mentioned using the 2.9.1 template, it comes with a lot of pregeneratred code and you just dump the html in the www folder. One thing I know it handled was Windows 8 not allowing get requests to local files which is why when using this on a Windows Phone you put the angular.bootstrap in the deviceready event handler so it does not try to load templates until phonegap's code is ready to run. That being said I have a few things you can try in the time being.

Unfortunately at the moment I don't have access to my Windows 8 machine, I develop on a Mac and am not in the office today so unless I get one of my co-workers to turn it on for me I can't get on and test your code. But if your running it as it is uploaded, try making the following changes.

in default.html, try uncommenting this

<script type="text/javascript">
        jQuery.isUnsafe = true;
</script>

and uncomment this in window.onload function

angular.bootstrap(document, ["helloAngularApp"]);

You'll need to either bootstrap it this way or add this to your html tag

<html ng-app='helloAngularApp'>

I bootstrapped mine in the deviceready event handler as phonegap has a way around the get requests to local files but since your not using their template or developing for a phone you can probably do it either way.

Apart from this I am not sure what to try as I have never tested my app in Windows 8 desktop, I would suggest opening up a new thread about the desktop issue, since this thread is about this issue with phones, and seeing how people are working around it. Maybe try the MSApp.execUnsafeLocalFunction() mentioned in the link in wideblue's post.

Also check out PhoneGap and see if they have templates for Desktop, I believe they do so even though their name is PhoneGap they have templates for OSX and Windows 8 desktop apps and they may have something for your case that you can drop your html into and get you started.

@sureshvsvb
Copy link

Hi Robert-W,

I figured out the issue. It is with jQuery for Windows8 - unable to add dynamic content issue. I downloaded some of the available jquery versions with fixes for W8. But they did not worked out.

After following Widblue comment, i have made the changes and it worked. Now templates are loading dynamically.

Thanks,
Suresh

@wideblue
Copy link
Author

wideblue commented Dec 9, 2013

@Asscher If you read this thread carefully you will see that it got polluted with issues from runing cordova app on W8 so now you are confusing things. Using jquery-1.8.0-windows8-ready.js will not help you run phonegap app on WP8.

@Asscher
Copy link

Asscher commented Dec 9, 2013

Okay i was confusing things indeed.
Can you please provide me full source code on github of your working version ?
What setup do i use to get it working with Cordova 3.2.0 ?

@wideblue
Copy link
Author

I don't have nice presentable sample to give, my test app is messy because I was just trying different things with it. I also don't have a WP8 device at the moment so that I could clean the app up and test it.
I suggest to you that you go trough following steps

1.) create a new cordova project using CLI ( http://cordova.apache.org/docs/en/3.2.0/guide_cli_index.md.html#The%20Command-Line%20Interface )
2.) put your clean Angular project (that works in the browser) inside www directory
3.) adapt the project so that angular gets manually bootstrapped after cordova devicesready event has fired
4.) Build the whole project with Visual studio to see if it maybe works (with current version of angular)
if not
5.) In angular.js change:

var xhr = new XHR();

to

var xhr = new XMLHttpRequest();

and put <script src=" YOUR PATH /jquery-2.0.3.min.js"></script> in index.html before angular.js

(as far i can remember didn't need to use <script>jQuery.isUnsafe = true;</script> and whitelisting as Robert-W did)

  1. Do the step 4 again, hope it works

@wideblue wideblue reopened this Dec 10, 2013
@Asscher
Copy link

Asscher commented Dec 11, 2013

I found my problem, the routing is actually working.
The Phonegap deviceReady event is not firing in WP8, this is why angular isn't bootstrapped and thus my routing isn't working.

@tomahim
Copy link

tomahim commented Jan 2, 2014

I'm currently having the same issue with angular 2.5, i'm not using cordova neither phonegap. I try to implement an application based on a simple WebView.

It seems that the routing isn't working like described sooner in this issue, I tried all the fixes but nothing...

I also access to an API secured by HTTPS. After some research I think that maybe the HTTPS is interpreted as a cross domain request, and this fire the "access denied" error. What do you think about this ?

@IgorMinar
Copy link
Contributor

is this still an issue with 1.2.7?

change 6c17d02 that was released with 1.2.7, could have possibly fixed part of the problem

the inconsistent use of http is problem of the application or os and not angular, so please ensure that you either user use http or https to avoid cross-origin issues.

@mlegenhausen
Copy link

I found the error lays in a different cordova project structure. You need to prepend www/ when calling local resources on Windows Phone 8. Also make sure your files get transfered to the phone (look in the Output window), some file types are ignore like json. To fix this look in your .csproj file.

@purplecabbage
Copy link

This all seems to be working fine in Cordova 3.4.0 for Windows Phone 8.
I was able to build and run RobertW's sample app without issue ( https://github.com/Robert-W/Angular-Win8 )

If people still have issues, please post a brief/clear/concise non-working example ( the contents of your www folder alone should be plenty )

Also, the issues with loading static files is probably because they are not part of the .csproj file. Visual studio automatically adds js/html files as 'resources' but some other types (ex. .json) are not.

@caitp
Copy link
Contributor

caitp commented Apr 16, 2014

👍 @purplecabbage

@aesculus
Copy link

@vko-online
Copy link

Cordova 3.5.0 Platform: windowsphone
Visual Studio 2013 WindowsPhone 8 Project WindowsPhone 8.1 Emulator
AngularJS v1.2.16
Tried suggesstions of @Robert-W (Downloaded sample, it works!)
But in my app i use $http requests to my http://localhost:60659/ backend (Already has Cors support!)
Ok now my index.html looks like below

<!DOCTYPE html>
<html class="no-js">
<head>
    <meta name="ommited"/>
    <link rel="ommited">
    <script src="externals/jquery/jquery-2.0.3.min.js"></script>
    <script>jQuery.isUnsafe = true;</script>
    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/app.js"></script>
   <ommited>
    <script>
        window.onload = function () {
            angular.bootstrap(document, ["opvko"]);
        };
    </script>
</head>
<body>
    <div class="container">
        <div ng-view=""></div>
    </div>
</body>
</html>

And also i added $sceDelegateProvider after config as @Robert-W suggested.

function ($sceDelegateProvider) {
    $sceDelegateProvider.resourceUrlWhitelist(['.*']);
});

But it doesn't work, i still get the same error

CordovaBrowser_LoadCompleted
Exception "System.SystemException" in Microsoft.Phone.Interop.ni.dll
Error calling js to fire nativeReady event. Did you include cordova.js in your html script tag?

If i turn on Javascript Exception handling, i see exactly place where exception thrown:

string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire()})();";
        try
        {
            CordovaBrowser.InvokeScript("execScript", new string[] { nativeReady });
        }
        catch (Exception /*ex*/)
        {
            Debug.WriteLine("Error calling js to fire nativeReady event. Did you include cordova.js in your html script tag?");
        }

Changed

string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire()})();";

to

string nativeReady = "(function(){ cordova.require('cordova/channel').onNativeReady.fire(); angular.bootstrap(document,['opvko']); alert('ready')})();";

Alert shown, another exception thrown in file XHRHelper.cs at:

if (resource == null)
            {
                // 404 ?
                Browser.InvokeScript("__onXHRLocalCallback", new string[] { "404" });
                return true;
            }
            else
            {
                using (StreamReader streamReader = new StreamReader(resource.Stream))
                {
                    string text = streamReader.ReadToEnd();
                    Browser.InvokeScript("__onXHRLocalCallback", new string[] { "200", text }); //<- here
                    return true;
                }
            }

As again @Robert-W suggested, tried to search var xhr = new XHR(); in angular.js But it doesn't contain this string! Only var xhr = createXhr(method);,
So i changed it to

//var xhr = createXhr(method);
var xhr = new XMLHttpRequest();

But no success. But this time only dummy error An unknown error has occurred. Error: 80020101.
After googling a little, and posting post in msdn itself, seems that this exception is thrown by javascript but index.html itself doesn't contain any errors in chrome either IE10-11.

So finally i made repo with whole vs project files. Please take a look, been struggling 2 days. Or at least could anyone make commit @Robert-W 's sample located here with $http

My working app in WindowsPhone emulator's browser
opvko

Edit

Added $http to @Robert-W 's sample, works. Turns out my app itself doesn't work, not because of $http. Going to use it as starting point, anyway please help to find out source of exception

Edit2

Started from @Robert-W 's sample. but came to the same place. Thought im including too much files, over 15, merged, finaly 8, but still the same =(

Finally

Figured out. After 3 days of hard work, found one email where some smart boy was writing to cordova team, about problem of XHRHelper.cs, he left 3 or 4 messages, with no reply, and in one of them he made better version and dropped link for that, now i cannot remember it, found it by accident, but i have that helper at this gist

All errors gone! angular works as expected!

@btford btford removed the gh: issue label Aug 20, 2014
@wideblue wideblue closed this as completed Sep 8, 2014
@fobin
Copy link

fobin commented Sep 23, 2014

@vko-online I have struggled with this also days. Works now like a charm. Thank you so much.

@kmkwak
Copy link

kmkwak commented Oct 13, 2014

Cordova 3.6.3
platform : wp8
AngularJS v1.2.6

Problems :

  • anchor tag : ng-href is not working.
  • routing : working with template, but not working with templateUrl.
  • $location.url(~~) : template is not applied.

Reason :

XHRHelper.cs
the script in InjectScript method is reloaded every time url is changed.
and variable __XHRShimAliases is initialized,
so __onXHRLocalCallback function is not properly working.

Solution :

  1. add following code in module config.
  $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel|x-wmapp0):/);
  $locationProvider.html5Mode(false);

I got a hint from http://www.stephenpauladams.com/articles/angularjs-cordova-windows-phone-quirk/
2. In this file (https://apache.googlesource.com/cordova-wp8/+/3.6.x/wp8/template/cordovalib/XHRHelper.cs),
I added following code in the first line of script.

...
string script = @"(function(win, doc) {
    if (window.XHRHelperInitialized) {
         return;
     }
      window.XHRHelperInitialized = true;

     var __XHRShimAliases = {};
...

@apreg
Copy link

apreg commented Oct 18, 2014

Thank you @kmkwak! You saved my life.
I'm using
Cordova v3.7.0.
AngularJS v1.2.20
Angular Translate v2.4.1
Angular translate loader static files was not able to load local .json files on WP8.1 w/o your tweaks.

@akozlov75
Copy link

@vko-online: Thnx man, real help!!!

@purplecabbage
Copy link

This will be available in the next release of cordova-wp8, thanks for pointing it out.
apache/cordova-wp8#65

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests