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'
}
}
]
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);
})
I am building a UI into a JAR for Spring Server. I have a bunch of Angular JS pages. I want to pass in a command line argument to my jar that tells it where the API server is like so:
java -jar application.jar --api=http://ip:9000
So my application.properties file has:
url=${api:http://localhost:9000}
The way I am currently doing is it just having a hardocoded js config file and on each of my .html pages:
<script src="../js/appName/config.angular.js"></script>
Which contains:
var configData = {
url:"http://localhost:9000"
};
And called in each file:
$scope.apiUrl = configData.url;
How do I tap into the applications.properties file that I can override with my JAR command line parameter during runtime vs. the way it has been coded now.
When you pass a value from command line and the same property name is present in properties file then spring boot overrides the value from command line. So to achieve what you want do something like this
In application.properties
#this is default value
app.url=localhost:8080
Create a class to map the properties value or you can use existing class or something else based on your project structure.
#Component
public class Sample {
#Value("${app.url}")
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Now when your execute a jar with argument --app.url="someserver:9090" the value will be overriden and you can use this value anywhere.
Note it will also work if you try to access the properties value directly in jsp using expression.
Try it, it works. I have used the same thing in my latest project which is a composite microservices and each component need each others url.
[Edit]
Reference : http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Am I getting it right: The client part is delivered by the application? So the part of the last sentence 'during runtime' has more the meaning of 'bootstrap/initial loading', right? One (old school) approach is to provide the entry html (e.g. index.html) through the application (a simple template engine) and provide the needed information with a setter in a JS config object:
// pseudo js code with thymeleaf
<script th:inline="javascript">
/*<![CDATA[*/
myConfig.url = [[${#httpServletRequest.remoteHost}]];
/*]]>*/
</script>
This is just a sample that will only set the remote host name but I think you get the idea.
Side note: I still don't really get why do you have to set this. If the application contains the client code, why do you work with absolute URLs for remote calls? (Disclaimer: I have only experience in Angular(2) and not with AngularJS)
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;
});
I try to study and use Backbone/Marionette in my project. Now I stuck with Router navigation which work not as I though it should.
class MyApp.Router extends Marionette.AppRouter
appRoutes :
'info/:place/(:what)' : 'places_page'
MyApp.Controller = ->
places_page: (place,what)->
console.log 'Triggered places_page'
MyApp.addInitializer( ->
controller = new MyApp.Controller()
new MyApp.Router
controller: controller
Backbone.history.start( pushState: false )
)
MyApp.vent.on('do:search', ->
console.log 'triggered do:search'
place = 'Moscow'
what = 'Пицца'
info_model.set place: place, item:what
new_url = 'info/'+where+'/'+what
if new_url != decodeURIComponent(Backbone.history.fragment)
Backbone.history.navigate(new_url, {trigger: false})
On initial load of site.com/#info/Budapest/Vine page or reload it, I get Triggered places_page message as I expect.
But when I fire do:search event which update url to site.com/#info/Moscow/Пицца, I get Triggered places_page again! So it reload all my views from scratch instead of just change url and re-render one model.
What I can do wrong here?
Update 2:
Found strange thing. If I use latin letters in new url, everything work like it should.
But if I use cyrillic in new url path, it will trigger route function.
Backbone: 1.0, Marionette:v1.0.3, jquery: 1.9.1
Mystery solved!
That happens because of non-latin symbols in url.
Correct code:
new_url = 'info/'+encodeURIComponent(where)+'/'+encodeURIComponent(what)
if new_url != Backbone.history.fragment
Backbone.history.navigate(new_url, {trigger: false})
Because Backboune.navigate don't execute navigate if url didn't change and trigger is false by default, I can write it simple like that:
new_url = 'info/'+encodeURIComponent(where)+'/'+encodeURIComponent(what)
Backbone.history.navigate(new_url)
Backbone.history takes an object when starting. Try this syntax in CoffeeScript:
Backbone.history.start
pushState: false
In addition, pushState is false by default, so you can just have Backbone.history.start()
Does this solve your issue?
Proper URL encoding is required. I couldn't find this in the docs of Backbone related to the router functionality.
I had the same issue, alas with spaces in the query part, i.e.:
#app/terms?filter=java ee
Together with the encodeURIComponent solution as described in your answer, I also found the following lines of comments in backbone.js (1.0.0), pertaining to the navigate function:
// Save a fragment into the hash history, or replace the URL state if the
// 'replace' option is passed. You are responsible for properly URL-encoding
// the fragment in advance.
I am using CakePHP 2.1.2 with PHP 5.3.5 and a plugin called 'Cakemenu' which normally works fine. The plugin stores menus in a db table with the menu link stored as text like
array('plugin'=>null,'controller'=>'assets','action'=>'index');
The helper in the plugin gets those values, then executes this code to convert that text to an array:
//Try to evaluate the link (if starts with array)
if (eregi('^array', $value['Menu']['link'])) {
$code = "\$parse = " . $value['Menu']['link'] . ";";
$result = eval($code);
if (is_array($parse)) {
$value['Menu']['link'] = $parse;
}
}
Everything works fine unless CakePHP is handling an error. For example if I mistype the name of a controller in the browser I should get a menu and then the missing controller message. Instead I get a page full "Parse error: syntax error, unexpected $end in..." messages pointing to the line with the eval statement. If I printout the variable that is getting eval'ed I see that it has been (incorrectly) encoded with Html entities when it normally does not.
Good string to be eval'ed:
$parse = array('plugin'=>null,'controller'=>'assets','action'=>'index');
Bad string to be eval'ed:
$parse = array('plugin'=>null,'controller'=>'Parts','action'=>'add');
To temporarily fix the problem I added two statements to just replace the offending characters
$value['Menu']['link'] = str_replace( ''','\'',$value['Menu']['link']);
$value['Menu']['link'] = str_replace( '>','>',$value['Menu']['link']);
and everything works great again. Some other pieces of information that might be helpful is that the array of data used to generate the menu is read during the beforeFilter of the app and saved in a view variable and then the menu is generated as an element in the view.
I'm thinking that the error causes CakePHP (or PHP) to skip some loading or configuration process and that causes the string to be mishandled. Any help would be appreciated, thanks
Your beforeFilter() method won't be executed on error pages. You'll have to handle your errors yourself and manually call beforeFilter(). I wrote a blog post on how to use custom error pages - pay close attention to the Controller Callbacks section.