How to get Angular UI Router to respect "non-routed" URLs - angular-ui-router

This is my first experience with AngularUI Router, so I guess I'm making a newbie error and hope somebody can guide me.
I've configured a single-page application to use Angular UI Router in HTML5 mode and it all seems to work as expected.
.config([
"$stateProvider", "$urlRouterProvider", "$locationProvider",
function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider.state("concept", {
url: "/concepts/:conceptKey",
templateUrl: "/templates/concept-view.html",
controller: "conceptViewController",
resolve: {
concept: [
"$stateParams", "conceptsApi",
function ($stateParams, conceptsApi) {
return conceptsApi.getConcept($stateParams.conceptKey);
}
]
}
});
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
}
])
However, the same page also contains some links to other static pages on the same site, using relative URLs. Prior to installing Angular routing, these links worked correctly, but now they are broken. Specifically, clicking any one of these links correctly changes the browser address bar, but does not trigger navigation to that destination page.
I assume I need to add something to tell the routing configuration to ignore certain URL patterns, but I haven't found any information that shows me how to do this. Any suggestions please?
Thanks,
Tim

After some investigation I discovered that this issue is not specifically related to Angular UI Router. The same behavior is also present in the native AngularJS routing mechanism and is caused by the link rewriting logic implemented by $location, as described in this documentation.
Further discussion of the problem is here.
I found two possible solutions, both of which seem to work well:
Explicitly target links to static pages: By including the attribute target="_self" in any links to static pages (i.e. pages that fall outside the defined Angular routing scheme) they will be ignored by AngularJS and thus rendered correctly.
Disable link re-writing: When configuring Angular routing in HTML5 mode, two syntax formats are supported. The simplest format ...
$locationProvider.html5Mode(true);
... enables HTML5 mode with the default configuration. However, the long-form syntax provides access to additional configuration properties, one of which solves the above problem by disabling Angular's default behavior of intercepting and re-writing link URLs:
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
});
I used the 2nd solution and it appears to have no adverse effect on the behavior of URLs defined in the routing scheme. This solution appears to work equally well with Angular UI Router and with native AngularJS routing.

Related

How to properly connect Nuxt.js with a laravel backend?

I am starting a new project, Nuxt.js for the frontend and Laravel for the backend.
How can I connect the two?
I have installed a new Nuxt project using create-nuxt-app, and a new laravel project.
As far as I have searched, I figured I need some kind of environment variables.
In my nuxt project, I have added the dotenv package and placed a new .env file in the root of the nuxt project.
And added CORS to my laravel project, as I have been getting an error.
The variables inside are indeed accessible from the project, and im using them
like this:
APP_NAME=TestProjectName
API_URL=http://127.0.0.1:8000
And accessing it like this:
process.env.APP_NAME etc'
To make HTTP calls, I am using the official Axios module of nuxt.js, and to test it i used it in one of the components that came by default.
The backend:
Route::get('/', function () {
return "Hello from Laravel API";
});
and from inside the component:
console.log(process.env.API_URL)//Gives 127.0.0.1:8000
//But this gives undefined
this.$axios.$get(process.env.API_URL).then((response) => {
console.log(response);
});
}
What am I doing wrong here?
I have tried to describe my setup and problem as best as I can. If I overlooked something, please tell me and I will update my question. Thanks.
Taking for granted that visiting https://127.0.0.1:8000/ in your browser you get the expected response, lets see what might be wrong in the front end:
First you should make sure that axios module is initialized correctly. Your nuxt.config.js file should include the following
//inclusion of module
modules: [
'#nuxtjs/axios',
<other modules>,
],
//configuration of module
axios: {
baseURL: process.env.API_URL,
},
Keep in mind that depending on the component's lifecycle, your axios request may be occurring in the client side (after server side rendering), where the address 127.0.0.1 might be invalid. I would suggest that you avoid using 127.0.0.1 or localhost when defining api_uris, and prefer using your local network ip for local testing.
After configuring the axios module as above, you can make requests in your components using just relative api uris:
this.$axios.$get('/').then(response => {
console.log(response)
}).catch(err => {
console.error(err)
})
While testing if this works it is very helpful to open your browser's dev tools > network tab and check the state of the request. If you still don't get the response, the odds are that you'll have more info either from the catch section, or the request status from the dev tools.
Keep us updated!
Nuxt has a routing file stucture to make it easy to set up server side rendering but also to help with maintainability too. This can cause Laravel and Nuxt to fight over the routing, you will need to configure this to get it working correctly.
I'd suggest you use Laravel-Nuxt as a lot of these small problems are solved for you.
https://github.com/cretueusebiu/laravel-nuxt

WebAPI SignalR Negotiate response different on different browsers

The main problem about Access-Control-Allow-Origin I think. But when I configure the Web API project as defined in the given documentation, it still not working in chrome and firefox but working in IE well (it is about IE thinks localhost is not cross domain, AFAIK). I tried different ways to make it work but no result.
I put the example project to github repository. Project is very simple. There are two applications working on cross domains. It is very simple chat application like in signalr examples.
You must change the value of api host in client javascript file:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApp/Scripts/app/chat.js#L2
When you open the Chat page in mvc project, there will be two requests to api application
1- Regular ajax request (which is working fine)
2- Signalr negotiate request (cancelled)
And also I don't think browser disables the CORS because of if it disables there would not be an hit to server. So I think it is about browser but not about browser disables (something else).
Details are in repository
Readme: https://github.com/yusufuzun/WebApiSignalR/blob/master/README.md
Fiddler Results: https://github.com/yusufuzun/WebApiSignalR/blob/master/FiddlerResults
The bad part about it also is server returning 500 with this error:
System.InvalidOperationException: 'chat' Hub could not be resolved.
Which hub name is chat also.
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Hubs/ChatHub.cs#L10
You can enable CORS for Web Api in project with different ways for test purposes. Each one is giving different errors all about XMLHttpRequest Access-Control-Allow-Origin.
I commented them, so you can uncomment and make test for each one:
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Global.asax.cs#L24
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L14
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/App_Start/WebApiConfig.cs#L16
https://github.com/yusufuzun/WebApiSignalR/blob/master/ChatApi/Controllers/ChatController.cs#L17
So what is going on here?
After I talked with David Fowler in JabbR, he mentioned the thing about using CORS with SignalR. My signalr startup code was wrong. So after changing the startup code like in his advice it worked well.
He also mentioned SignalR and Web API are working with different CORS definitions. So enabling or disabling one doesn't affect other.
Here is the new startup code:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
map.RunSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
});
});
The old one:
app.MapSignalR(new HubConfiguration()
{
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
}).UseCors(CorsOptions.AllowAll);
Hope it helps to somebody out there.

Angular JS $http request does not reach the server in ie8

I'm having issues with using $http on ie8. The request does not reach the server, until I hit a refresh. Coming back to the same link still has the same problem until I hit refresh again.
The weird thing is if the web server is on LAN and the request is made to a server in LAN, it works fine. But if the webserver is hosted remotely, it does not work!
Here is the code:
Index.html
{{test}}
Controller
app.controller(
"TestController",
function( $scope, $http) {
var url = '/test/get_data';
$http.get(url).success(function(data) {
$scope.test = data;
});
}
);
I got this error: TypeError: Object doesn't support this property or methodundefined
I prepared a JSFiddle earlier but JSFiddle is broken in ie8 so I don't provide it here.
Unfortunately I don't have a remote server that I can share with you.
Edit
Previously I used an external url which gave me 'Access Denied' error in ie because of Same Origin Policy as mentioned by one answer below. But this was not my original problem. I still have the issue above when request is from the same origin
This is a cross domain request, which is not allowed in ajax because of Same Origin Policy.
There are two solutions for this
1. JSONP: It is a cross browser way to handle cross domain ajax requests using javascript callback mechanism
2. CORS: It is a HTML5 standard, it is implemented by most of the modern browsers except IE
Mongodb lab is not supporting jsonp since it has support for CORS, that is why your request is failing in IE and works in Chrome and other browsers.
As per this post they do not have any plan to support jsonp, so I don't thick there is a way to make this work in IE.
So I found the fix... Hope this helps anyone out there that experience this problem
Angular script needs to be loaded after jQuery. I didn't have this because Yii framework that I use autoloads jQuery and the angular was not included after the jQuery.
All the controller functions need to be at the end of body section (just before the closing )
Updating to angular 1.0.5 seems to fix the problem. The problem occurred in 1.0.4 with all the above tricks. I think is related to fix 791804bd

Issue with METHOD in prototype / Ajax.Request

I am trying to call yahoo api via Ajax to find current weather:
var query = "select * from weather.forecast where location in ('UKXX0085','UKXX0061','CAXX0518','CHXX0049') and u='c'";
var url = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent(query) +'&rnd=1344223&format=json&callback=jsonp1285353223470';
new Ajax.Request(url, {
method: 'get',
onComplete: function(transport) {
alert(transport.Status); // say 'null'
alert(transport.responseText); // say ''
}
});
I noticed, that instead of GET firebug says OPTIONS. What is it and how I can use force prototype to use GET?
Here is functionality which i am trying to recreate.
And here is full URL which I am trying to access:
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20location%20in%20(%27UKXX0085%27%2C%27UKXX0061%27%2C%27CAXX0518%27%2C%27CHXX0049%27)%20and%20u%3D%27c%27&rnd=1344223&format=json&callback=jsonp1285353223470
After hours of trying to debug the same issue myself, I came to the following conclusion.
I believe this happens because of XSS counter-measures in newer browsers.
You can find very detailed information about these new counter-measures here:
https://developer.mozilla.org/en/http_access_control
Basically, a site can specify how "careful" the browser should be about allowing scripts from other domains. If your site, or a site from which you're loading external JavaScript code, includes one of these pieces of "browser advice", newer browsers will react by enforcing a stronger XSS policy.
For some reason, Prototype's Ajax.Request, under Firefox, seems to react by attempting to do an OPTIONS request, rather than a GET or POST, so perhaps Prototype has not been updated to correctly handle these new security conditions.
At least that was the conclusion in my case. Maybe this clue can help with your case...

Http Modules are called on every request when using mvc/routing module

I am developing a http module that hooks into the FormsAuthentication Module through the Authenticate event.
While debugging i noticed that the module (and all other modules registered) gets hit every single time the client requests a resource (also when it requests images, stylesheets, javascript files (etc.)).
This happens both when running on a IIS 7 server in integrated pipeline mode, and debugging through the webdev server (in non- integrated pipeline mode)
As i am developing a website with a lot images which usually wont be cached by the client browser it will hit the modules a lot of unnessecary times.
I am using MVC and its routing mechanishm (System.Web.Routing.UrlRoutingModule).
When creating a new website the runAllManagedModulesForAllRequests attribute for the IIS 7 (system.webServer) section is per default set to true in the web.config, which as the name indicates make it call all modules for every single request.
If i set the runAllManagedModulesForAllRequests attribute to false, no modules will get called.
It seems that the reason for this is because of the routing module or mvc (dont know excactly why), which causes that the asp.net (aspx) handler never gets called and therefore the events and the modules never gets called (one time only like supposed).
I tested this by trying to call "mydomain.com/Default.aspx" instead of just "mydomain.com/" and correctly it calls the modules only once like it is supposed.
How do i fix this so it only calls the modules once when the page is requested and not also when all other resources are requested ?
Is there some way i can register that all requests should fire the asp.net (aspx) handler, except requests for specific filetype extensions ?
Of course that wont fix the problem if i choose to go with urls like /content/images/myimage123 for the images (without the extension). But i cant think of any other way to fix it.
Is there a better way to solve this problem ?
I have tried to set up an ignoreRoute like this routes.IgnoreRoute("content/{*pathInfo}"); where the content folder contains all the images, javascripts and stylesheets in seperat subfolders, but it doesnt seem to change anything.
I can see there a many different possibilites when setting up a handler but I cant seem to figure out how it should be possible to setup one that will make it possible to use the routing module and have urls like /blog/post123 and not call the modules when requesting images, javascripts and stylesheets (etc.).
Hope anyone out there can help me ?
Martin
The problem seems to be the routing module.
The solution is to move images, css, js to a subdomain, or you can probably register which filetypes/extensions the routing module should ignore.
The following code is what I use in every MVC Application in order to avoid the overhead caused by the routing system on serving static files, javascript, css, etc:
public static void RegisterRoutes(RouteCollection routes)
{
routes.RouteExistingFiles = false;
routes.LowercaseUrls = true;
routes.AppendTrailingSlash = true;
routes.IgnoreRoute("Content/{*pathInfo}");
routes.IgnoreRoute("Scripts/{*pathInfo}");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = #"(.*/)?favicon.ico(/.*)?" });
/* ... */
}

Resources