Custom encoding for urls using Angular 2 Router (using a + sign in place of a space)

萝らか妹 提交于 2019-11-27 02:19:30

问题


I am using an Angular 2 Router to update the query params in a URL for a search application. I am attempting to replace spaces in a query with + signs. However, + signs are getting encoded. For example:

this.router.navigatebyUrl('?q=one+two');

populates the URL with "?q=one%2Btwo".

In looking at the source code for Angular 2, it looks like the router converts the URL to a UrlTree which uses encodeURIComponent() to encode the url. Because of this, it is impossible to prevent the default encoding.

My current process is that I change the route by doing navigateByUrl as seen above, and then listen for changes with:

this.routeSubscription = this.route.queryParams.subscribe((params: any) => {
  this.term = (params.q ? params.q : '');
});

Is there an alternate way to deal with query parameters that would allow me to use my own strategy for url encoding?


回答1:


I was able to find a solution to my problem. You can make own custom url serializer by implementing the UrlSerializer class.

Custom Url Serializer

Create a custom url serializer like this:

class CustomUrlSerializer implements UrlSerializer {
    parse(url: string): UrlTree {
        // Custom code here
    }

    serialize(tree: UrlTree): string {
        // Custom code here
    }
}

Then, you just need to provide the CustomUrlSerializer in place of the UrlSerializer, which you can place in the AppModule providers array after importing both serializers.

providers: [
    { provide: UrlSerializer, useClass: CustomUrlSerializer },
    ...
]

Now, when you call router.navigate or router.navigateByUrl, it will use your custom serializer for parsing and serializing.

Using + signs as spaces

To parse + signs as spaces:

parse(url: string): UrlTree {
    // Change plus signs to encoded spaces
    url = url.replace(/\+/g, '%20');
    // Use the default serializer that you can import to just do the 
    // default parsing now that you have fixed the url.
    return this.defaultUrlSerializer.parse(url)  
}

And for serializing:

serialize(tree: UrlTree): string {
    // Use the default serializer to create a url and replace any spaces with + signs
    return this.defaultSerializer.serialize(tree).replace(/%20/g, '+');
}

DefaultUrlSerializer




回答2:


I ran into an issue specifying the custom provider. There was apparently a circular dependency when compiling with the --prod flag causing an error with the text: useClass cannot by null. This is how I worked around that error:

In AppModule, define the following:

const customUrlSerializer = new CustomUrlSerializer();
const CustomUrlSerializerProvider = {
    provide: UrlSerializer,
    useValue: customUrlSerializer
};

Then in the providers array, add the provider you specified above.

...
providers: [CustomUrlSerializerProvider]
...


来源:https://stackoverflow.com/questions/39541185/custom-encoding-for-urls-using-angular-2-router-using-a-sign-in-place-of-a-sp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!