nginx rewrite Issue, why does it just replaces one matched string? - nginx

I want to replace my url via Nginx's rewrite directive. For instance, the client side requests http://127.0.0.1/user/user_id/, and I want to let Nginx rewrite the url to http://127.0.0.1/person/person_id/.
My Nginx configuration is like this:
rewrite (.*)user(.*) $1person$2;
But I fount the Nginx changes the url to .../user/person_id/
Could someone tell me how to change the user to person via rewrite directive?

Assuming that the first instances of user and personare constant and that there is always a slash after the second item, you can try:
rewrite ^/user/user_([^/]+)/(.*)$ /person/person_$1/$2 ;

well this single case you are talking about can be solved simple:
rewrite ^/user/user_id/(.*)$ /person/person_id/$1 ;

Related

Nginx rewrites with %3F

For a site running Mediawiki, I have this config for clean URLs:
rewrite ^/wiki/([^?]*)(?:\?(.*))? /wiki/index.php?title=$1&$2 last;
This works fine except when the page title needs to have a question mark. For a URL like /wiki/Who_is_your_daddy%3F_It_is_me the correct rewritten URL is /wiki/index.php?title=Who_is_your_daddy%3F_It_is_me. However, Nginx is rewriting to /wiki/index.php?title=Who_is_your_daddy&_It_is_me.
What is the correct rewrite rule?
The query string is not part of the normalised URI that is processed by the rewrite directive's regular expression. However, the query string will be automatically appended to the rewritten URI, so you don't need to do anything to include the &action=edit part. See this document for details.
The %3F in the original request will be normalised to a ? by the time that rewrite is processing it. You will need to capture both sides of the ? to manually translate it back to %3F in the new query string.
You can use more than one rewrite statement, so that the case with and without a %3F are both handled correctly.
For example:
rewrite ^/wiki/(.*)\?(.*)$ /wiki/index.php?title=$1%3f$2 last;
rewrite ^/wiki/(.*)$ /wiki/index.php?title=$1 last;

Nginx forwarding to different app's different path using `#` symbol

Quick question. We have two apps. Ports 3001 and 3002. Our domain is www.domain.com.
What we want to have it once person enters www.domain.com/pathname we want them to be redirected into another app's specific path.
How to do it?
We already came up to this in my nginx
location /pathname/ {
proxy_pass http://127.0.0.1:3002/;
}
It nearly works. However, our app under 3002 works on path /#/pathname.
We can access it by typing www.domain.com/pathname/#/pathname. We want to access same link by typing www.domain.com/pathname.
How to shorten it? What do I miss?
(upd) Just redirect /pathname to /pathname/#/pathname
According to your comment, you want just redirect from /pathname to /pathname/#/pathname
Try these combined directives:
rewrite to append # and fragment identifier
and proxy_pass to reverse proxy to the app.
E.g.:
location /short_path_name/ {
rewrite ^ /pathname/#/$uri permanent;
break;
}
location /pathname/ {
proxy_pass http://127.0.0.1:3002/;
}
And use www.domain.com/short_path_name/ link for your app.
Unfortunately, nginx can't see the fragment identifier
Unfortunately, you can't. Because server never get the fragment identifier from browser.
The fragment identifier functions differently to the rest of the URI: its processing is exclusively client-sided with no participation from the web server
Naming a bit amusing, but it has a long history. See TBL (1997): Fragment Identifiers on URIs:
The URI reference is a thing you build by taking a URI for an information object, adding a "#" sign and then a Fragement identifier. (The last term is historical, so try not to thinl of it necessarily identifying a fragment).
Workarounds
There are workarounds, e.g. encode hashtag symbol into %23 but I'm not sure is it your way.
Handle request arguments with nginx
Note: rewriting url, nginx can preserve request arguments if you add ? at the end of rewrite directive.
See Nginx rewrite manual:
If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:
rewrite ^/users/(.*)$ /show?user=$1? last;

Is it possible to rewrite to a URL with a fragment in it in nginx?

E.g.
rewrite ^/page /#page;
I'm not sure if this would even be possible, due to the nature of fragments (never sent to the server etc). But since I'm rewriting TO one, rather than FROM one, I think it should work?
In which case how do I encode/escape that hash sign so that it doesn't start a comment..?
Thanks!
As you know, the fragment is used by the browser and is not sent to the server.
But you can use nginx to rewrite a request into a new URI containing a fragment, but it only makes sense if the new URI is sent to the browser, i.e by using an HTTP 3xx response.
The rewrite directive will generate an HTTP 3xx response when the redirect (302) or permanent (301) flag is provided (or the replacement string starts with a scheme - see this document for more).
For example:
rewrite ^/page /#page redirect;
Adding quotation marks, could help. I tried in Docker Nginx latest image (1.17.4)
rewrite ^/page "/#page" redirect;

Rewrite a url and rerun the server block

I'm trying to rewrite a url like the following but without sending a 301 to the client (change the url and then restart processing of the server block with the new url).
rewrite ^/a/b/$ /a/c/d permanent;
I would normally just reorder the lines but it's a really convoluted config and also really large.
permanent always means redirect, replace it with last
check the last flag in the reference page

Nginx Rewrite to another path on the server

Is it possible to do a rewrite rule in nginx to rewrite to another location on the server, outside of the current account?
For example, I want to rewrite image123.jpg to location on the server /dev/shm/123.jpg. Is this possible?
I could grab the image with a PHP script and rewrite to that, but I'd rather it was done more efficiently.
yes it's possible: have a look at the alias-directive

Resources