Dynamically setting the BaseUrl within configuration in Symfony2 - apache

I know that within Symfony2's configuration, there is no reference to the base url, as there is no request; the application could either run in cli or within a web server, and therefore we cannot rely on request. But still, I have configuration that asks for stylesheets or javascript base url (such as the JQueryHelperBundle, where you can set your jquery local path - being the local url). The thing is, is there a way to dynamically set a base url for the configuration, without having to change it so that:
The application can move from any directory under development, whether www/myproject or www/foo/myproject without having to change the settings
Production would work the same, except that rewriting the base url with apache would be detected (virtualhosting is common, where the baseurl is mapped to the web directory as '/').
Is there a way to get that base url information? Would using the difference between $_SERVER['DOCUMENT_ROOT'] minus the kernel root dir be a way to detect such base url? But what about virtualhost rebasing the url to / on the web directory? Hardcoding the base url completely couples the project to where it stands in development, and moving project around would require to change the base url everytime, which is annoying.
So, is there a way to dynamically detect the base url within Symfony2's configuration, according to the environment, without depending on the request?

I had to do that in a service, so I injected the router service in my own service and then:
$baseUrl = $router->getContext()->getHost();
But I considered it more as an hack that a real fixture of Symfony2 framework. For instance, in Controller you can generate absolute url easily (example from the symfony book):
$router->generate('blog_show', array('slug' => 'my-blog-post'), true);
And in the twig template, you have the {{ url }} function
I hope this help

Related

Dynamically change API route for SPA

I am currently building a SPA app using Vue.js and webpack to do our bundling. The backend API is built with .Net Core. When running locally, the Vue app is hitting localhost on the backend. I need to be able to change the route of the API dynamically based on the environment. Is there a way to do this without having to do a big switch statement that considers the current url? A requirement is that we are not allowed to change the webpack bundle for different environments, in other words, once it is bundled, it has to stay bundled. I have tried to pass static config files through to the bundle and dynamically change them based on the environment, but unfortunately that does not work, as it hits the values that were originally in them.
webpack dev server has a proxy capability. You could use this to proxy to your locally running backend when developing.
https://webpack.js.org/configuration/dev-server/#devserver-proxy
e.g. you can point anything from '/api' to 'localhost:8888/api' with the config.
Is your app the backend running on the same url when deployed? If not, you'll likely need a reverse proxy to pass along the requests to the backend.
You can use an axios interceptor so you only have that switch in one place:
axios.interceptors.request.use(config => {
// check location.host name and append the backend url you want
});
see https://github.com/axios/axios#interceptors
However, this is a little dangerous as the URLs in your switch statement will be strings, and therefore all of your environment URLs can be pulled out of your code even if minified/concatenated.
Another option is to add some sort of endpoint to the server your client side code is hosted, and when you start your app, query for that configuration.

How to enable offline support when using HTML5 history api

What are the best practices (and how to go about doing it) to support offline mode when using html5 history api for url rewrites?
For example, (hypothetically) I have a PWA SPA application at https://abc.xyz which has internationalization built in. So when I visit this link, the Vue router (which ideally could be any framework - vue, react, angular etc.) redirect me to https://abc.xyz/en.
This works perfectly when I am online (ofcourse, the webserver is also handling this redirect so that app works even if you directly visit the said link).
However, its a different story when I am offline. The service worker caches all resources correctly so when I visit the URL https://abc.xyz everything loads up as expected. However, now if I manually type the URL to https://abc.xyz/en, the app fails to load up.
Any pointers on how to achieve this?
Link to same question in github: https://github.com/vuejs-templates/pwa/issues/188
Yes, this is possible quite trivially with Service Workers. All you have to do is to configure the navigateFallback property of sw-precache properly. It has to point to the cached asset you want the service worker to fetch if it encounters a cache miss.
In the template you posted, you should be good to go if you configure your SWPrecache Webpack Plugin as follows:
new SWPrecacheWebpackPlugin({
...
navigateFallback: '/index.html'
...
})
Again, it is absolutely mandatory that the thing you put inside navigateFallback is cached by the Service Worker already, otherwise this will fail silently.
You can verify if everything was configured correctly by checking two things in your webpack generated service-worker.js:
the precacheConfig Array contains ['/index.html', ...]
in the fetch interceptor of the service worker (at the bottom of the file), the variable navigateFallback is set to the value you configured
If your final App is hosted in a subdirectory, for example when hosting it on Github pages, you also have to configure the stripPrefix and replacePrefix Options correctly.

Prevent access to public webpack bundle? ExpressJS

In my webpack config I have the publicPath set like so:
publicPath: '/js'
This way it points to public/js. Also in my index.pug file, which is loaded by the server and not in the public folder I have this:
extends layout
block content
main#app
script(src="/js/bundle.js")
Unfortunately, this enables people accessing my site to visit example.com/js/bundle.js. Is there a way to prevent this?
If /js/bundle.js is a script file you are using in your web page, then there is NO way to prevent the browser from going directly to http://example.com/js/bundle.js. That's the exact URL that the browser uses to load the script from your web page so that URL has to work.
ALL Javascript that runs in your web page is openly available to the public. You cannot change that. That's the architecture of the web and browsers.
Unfortunately, this enables people accessing my site to visit example.com/js/bundle.js. Is there a way to prevent this?
No. You cannot prevent it.

Tell Apache not to freak out over 404, and allow Ember-CLI router/adapter logic handle slug in URL

My new Ember-CLI app uses a user portal slug in the URL to display proper information to the user. For example (fake URL): http://my.server.portals.com/robertplant
I'm using a combination of router and adapter logic to get the user portal name form the url slug, and then display the data related to it. It probably needs some more work, but here's what I have so far:
Router code extract:
Router.map(function () {
this.route('portal', {path: '/:portal_slug'}, function () {
this.resource('account', {path: '/'});
});
});
Adapter code extract (for hitting the right API end point based on portal):
namespace: function () {
var portal = window.location.pathname.match(/^\/([^\/]*).*$/)[0];
return 'abc' + portal + '/api/v1';
}.property().volatile(),
I can hit the app locally (e.g.: http://localhost:4200/robertplant/) with no issues. It runs using Ember-CLI’s built in web server.
However, when I move the app to the server, which runs Apache, and try to hit it (e.g.: http://my.server.portals.com/robertplant), I get:
Not Found
The requested URL /robertplant was not found on this server.
Which makes sense I suppose, since there isn’t really a directory named the same as the slug. However, there has to be a way, I would think, to tell Apache to ignore the problem it thinks it is having, and allow the app router to handle it. The local web server is doing it somehow.
Ideally, the solution would leave the URL displayed the same. Also, re-writing the request to point to something like http://my.server.portals.com?slug=robertplant causes Ember-CLI assets to be looked for at the wrong path (can't set baseUrl dynamically).
I'd appreciate any feedback on how to set up the app in Apache to allow for this to happen.
Solution:
Say the current subdomain is my.portal.com. Create another subdomain that points to the same directory on the server. Name it my2.portal.com
For the first subdomain, add a mod rewrite rule which rewrites something like
http://my.portal.com/joe_blow
as
http://my.portal.com?portal_slug=joe_blow
This allows you to hit the url without a 404.
Set the asset paths (in the generated index.html) to point to the second subdomain. E.g.:
http://my2.portal.com/assets/app_name.js
This allows the app to find the assets without the issues associated with the rewrite or the slug in the url.
Of course, you can also place the assets anywhere else, including an S3 bucket. But in my case, I have a constraint of having to store them on the same server/network for security reasons. And my way you can deploy all the files to the same location.
That's it! Works like a charm.
The only thing I'm not fond of, is having to edit the index file after it's generated. I will try to automate it at some point.

Making Laravel understand proxy domain htaccess rule

I have a setup in Laravel whereby I have different sections of the site powered by one codebase. A section is defined by the first slug of the uri:
localhost.dev/section1/feature
localhost.dev/section2/another/feature
However, I also have a domain alias/proxy for these so that each section can have its own independent branding and SEO without splitting up the codebase.
section1.dev/feature (alias of localhost.dev/section1/feature)
section2.dev/another/feature (alias of localhost.dev/section2/another/feature)
However, Symfony's HTTPFoundation appears to be too smart to be fooled by this proxy, and whenever you use URL::full() or URL::current(), the domain remains localhost.dev despite your browser telling you that you're on section1.dev or section2.dev
Is there a way to configure .htaccess differently, or is there a way to make Laravel's URL::full() or URL::current() mirror what's in your address bar?
First: a domain alias is not a proxy.
Second: the app.url config option gets used by the application to generate URLs. Try making it an empty string.