As you know Laravel4 omits the trailing slashes from all URLS.
I've Laravel4 X AngularJS SPA (Single Page Application), and simply my current URLs looks like this:
http://localhost/en#/nglink
What I'd like to achieve is to make links looks like this:
http://localhost/en/#/nglink
So as you can see, I need a prefix slash before the AngularJS links (#/nglink), or a trailing slash after Laravel's links (http:// localhost/en). Is there anyway to achieve this using AngularJS? If not how to achieve it without editing Laravel's core files?
Well, it's possible to achieve that though either AngularJS or Laravel or http server side, but it's better & easier to be done through Laravel itself since we can just override the required classes (URLGenerator mainly) without touching core files, and while keeping the code (server agnostic), so it could work with apache/nginx or any other server with trailing slash (that's why I preferred not to work with htaccess).
Update #1
Laravel 5 / AppServiceProvider::register()
$this->app->bindShared('url', function ($app) {
$routes = $app['router']->getRoutes();
$request = $app->rebinding('request', function ($app, $request) {
$app['url']->setRequest($request);
});
// This is your custom overridden "UrlGenerator" class
$urlGenerator = new UrlGenerator($routes, $request);
return $urlGenerator;
});
Related
I am using undertow to statically serve a react single page application. For client side routing to work correctly, I need to return the same index file for routes which do not exist on the server. (For a better explanation of the problem click here.)
It's currently implemented with the following ResourceHandler:
ResourceHandler(resourceManager, { exchange ->
val handler = FileErrorPageHandler({ _: HttpServerExchange -> }, Paths.get(config.publicResourcePath + "/index.html"), arrayOf(OK))
handler.handleRequest(exchange)
}).setDirectoryListingEnabled(false)
It works, but it's hacky. I feel there must be a more elegant way of achieving this?
I could not find what I needed in the undertow documentation and had to play with it to come to a solution. This solution is for an embedded web server since that is what I was seeking. I was trying to do this for an Angular 2+ single page application with routing. This is what I arrived at:
masterPathHandler.addPrefixPath( "/MY_PREFIX_PATH_", myCustomServiceHandler )
.addPrefixPath( "/MY_PREFIX_PATH",
new ResourceHandler( new FileResourceManager( new File( rootDirectory+"/MY_PREFIX_PATH" ), 4096, true, "/" ),
new FileErrorPageHandler( Paths.get( rootDirectory+"/MY_PREFIX_PATH/index.html" ) , StatusCodes.NOT_FOUND ) ) );
Here is what it does:
the 'myCustomServiceHandler' provides the handler for server side logic to process queries sent to the server
the 'ResourceManager/FileResourceManager' delivers the files that are located in the (Angular) root path for the application
The 'FileErrorPageHandler' serves up the 'index.html' page of the application in the event that the query is to a client side route path instead of a real file. It also serves up this file in the event of a bad file request.
Note the underscore '_' after the first 'MY_PREFIX_PATH'. I wanted to have the application API URL the same as the web path, but without extra logic, I settled on the underscore instead.
I check the MIME type for null and serve index.html in such a case as follows:
.setHandler(exchange -> {
ResourceManager manager = new PathResourceManager(Paths.get(args[2]));
Resource resource = manager.getResource(exchange.getRelativePath());
if(null == resource.getContentType(MimeMappings.DEFAULT))
resource = manager.getResource("/index.html");
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, resource.getContentType(MimeMappings.DEFAULT));
resource.serve(exchange.getResponseSender(), exchange, IoCallback.END_EXCHANGE);
})
Are there any js plugins for angular based frontend that has a standard way of collecting data for analytics on users based on the browser fingerprinting libraries like fingerprint2.js or clientjs?
I don't think there is a solution for this question in AngularJS or in Angular 2/4.
But I have managed to do this using followings. Any one will work -
clientjs.org
Custom working example
Basically, both ways mentioned above reads localstorage to check if 10 digit number has been stored(with key name) or not. If it has, just use that or else generate new and store it in localstorage.
return checksum([
navigator.userAgent,
[screen.height, screen.width, screen.colorDepth].join('x'),
new Date().getTimezoneOffset(),
!!window.sessionStorage,
!!window.localStorage,
map(navigator.plugins, function (plugin) {
return [
plugin.name,
plugin.description,
map(plugin, function (mime) {
return [mime.type, mime.suffixes].join('~');
}).join(',')
].join("::");
}).join(';')
].join('###'));
I'm trying to use dot (.) in query string parameter but its not working.
This URL is working fine:
http://localhost:9000/search-result?majTFMin=0&majTFMax=100&majDOMCFMin=0&majDOMCFMax=100&majRefDomainsMin=0&majRefDomainsMax=100&majRefIPsMin=0&majRefIPsMax=100&majRefDomainsEDUMin=0&majRefDomainsEDUMax=100&majRefDomainsGOVMin=0&majRefDomainsGOVMax=100&selectedTLDs=com
But not this one as it contains a dot in a parameter:
http://localhost:9000/search-result?majTFMin=0&majTFMax=100&majDOMCFMin=0&majDOMCFMax=100&majRefDomainsMin=0&majRefDomainsMax=100&majRefIPsMin=0&majRefIPsMax=100&majRefDomainsEDUMin=0&majRefDomainsEDUMax=100&majRefDomainsGOVMin=0&majRefDomainsGOVMax=100&selectedTLDs=co.uk
When I'm trying to open above URL (with dot), it just prints:
Cannot GET /search-result?majTFMin=0&majTFMax=100&majDOMCFMin=0&majDOMCFMax=100&majRefDomainsMin=0&majRefDomainsMax=100&majRefIPsMin=0&majRefIPsMax=100&majRefDomainsEDUMin=0&majRefDomainsEDUMax=100&majRefDomainsGOVMin=0&majRefDomainsGOVMax=100&selectedTLDs=co.uk
And nothing else, not even any HTML tags(has checked that in view source)
I have read lots of posts which says that . can be used in query string without encoding, but I don't understand why its not working here. I think it has some issue with AngularJS.
I'm using ui-router for state change and passed value to controller.
Any help would be appreciated.
If you are using connect-history-api-fallback on your server (like lite-server does), the URLs with a dot are not rewritten by default.
connect-history-api-fallback code
if (parsedUrl.pathname.indexOf('.') !== -1) {
logger(
'Not rewriting',
req.method,
req.url,
'because the path includes a dot (.) character.'
);
return next();
}
Starting with connect-history-api-fallback version 1.2.0 the URLs with dots are allowed and you can solve this problem by using a a rewrite roule
Example
If your URL with dot is /search-result and you angular app lives in the index.html page you can add a rewrite rule to the connect-history-api-fallback like this
rewrites: [
{
from: /^\/search-result/,
to: 'index.html'
}
}
]
I am new to Angularjs and I would like to add dynamic subdomain such as sub.domain.com.
By changing sub, I would be able to ask the proper data from the server. However, the home page will still be the same.
sub1.domain.com and sub2.domain.com will have the same home.tpl.html page except that the data returned will be specific to the domain.
It will be the same for other pages too.
Is there a way to do that?
The main thing you need to look at is the $location service, in particular the $location.host() method. That will return you the full domain, from there it is easy to get the subdomain and use that.
You could even do a really simple service that you could inject anywhere to get access to the subdomain easily.
Something like:
app.factory('subdomain', ['$location', function ($location) {
var host = $location.host();
if (host.indexOf('.') < 0)
return null;
else
return host.split('.')[0];
}]);
Then you can use this as a simple injectable value in your controllers, directives, etc.
app.controller('SomeCtrl', ['$scope', 'subdomain', function ($scope, subdomain) {
// use subdomain same as any other variable
}]);
Subdomains are served by server, angular in turn serves hash/hashbang urls and knows nothing about subdomain.
U can have 3 subdomain, for example:
en.example.com (configured manually on server)|
de.example.com (configured manually on server)| -> example.com
it.example.com (configured manually on server)|
Each of them refers to the main example.com, but you wanna achieve something by using subdomains, for example i18n (with angular).
Thus, when someone connects to en.example.com (in fact, the request goes to example.com where you angular app is hosted) you can extract subdomain in angular(en in this case, see example in the post above) and translate you angular view.
Why no split by dots and count the elements of host()?
var host = $location.host();
var parts = host.split('.');
var subdomain = null;
// more than domain.cn, will always return the first
if (parts.length > 2)
subdomain = parts[0];
return subdomain;
hope it helps!
I am trying to use a cookie that is set by other page in my domain to authenticate the user.
Say I have needpassword.example.com written using cakephp,
and the cookie is generated by auth.example.com (using a Perl CGI program).
To login in to needpassword.example.com, I need to redirect to auth.example.com to set the cookie, and then use CakePHP to parse the cookie.
How do I parse this cookie? And how do I modify the Auth component to do these?
And how can I override the Auth class to instead go to the auth.example.com to authenticate, and not using the User model? By overriding the identify method in Auth.php?
Many thanks.
Since your needs sound outwith AuthComponent's originally intended design you have two options.
Firstly, if it really doesn't fit your needs, you could create and maintain your very own AuthComponent. Do this by copying /cake/libs/controller/components/auth.php to /app/controller/components/auth.php.
This would allow you to rewrite the component completely, but the downside is you will no longer receive updates to AuthComponent when you upgrade cake.
Secondly, you can extend just about anything in CakePHP using the following pattern:
// save as: /app/controllers/components/app_auth.php
App::import('Component', 'Auth');
class AppAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
// do stuff
return parent::indentify($user, $conditions);
}
}
.. and replace all instances of AuthComponent in your controllers with your AppAuthComponent.
You only need to define the methods you wish to replace.
You can run methods from the original AuthComponent (even ones you have redefined) at any point during your methods using parent::...
The method arguments should remain in the same order as the original API for consistency.
If you wish to add more method arguments, put them after the API ones, eg:
function identify($user = null, $conditions = null, $custom = array()) { ... }
This approach allows you to make application-specific customisation while still using the latest methods defined in the core where necessary.
Presuming I understand your question... As long as auth.example.com sets the cookie with the domain ".example.com" the users browser will send it along with the request to needpassword.example.com and you will be able to access it in your PHP script with the following:
$auth = $_COOKIE['auth'];
You can then make changes to the cookie with the following:
setcookie( "auth", "value", time() + 300, "/", ".example.com" );
(Note: time() + 300 sets the cookies expiry date to 5 minutes in the future, you may want to change this)