Rails url attribute's value cannot contain symbol '#' - ruby-on-rails

I've tried send request like this.
localhost:3000/ws/job_histories/index?agent_id=#1000
But on Controller I've received agent_id='' or like this one
localhost:3000/ws/job_histories/index?agent_id=10#00
I've received agent_id='10'. I think problem has because Rails understand it like comment.
How can I correctly received my data. Rails doesn't give me any exception.

The hash symbol is the fragment identifier and your browser will not send it to the webserver ever.
If you want to send it you need to URL encode it (%23), you can achieve that with CGI.escape('#').

This is completely normal, hashes belong to the client, they are not sent to the server.
And # is what represent a hash so remove it or encode it

Hash fragments aren't sent to servers from the browser, so this would never work, for any server-side framework, not just Rails.
From Wikipedia, Fragment identifiers:
Clients are not supposed to send URI-fragments to servers when they retrieve a document...
From URL Fragments and Redirects:
The Fragment component of the URL is the end of the URL from the hash symbol (#) onward. URL Fragments are never sent to the server in the HTTP request...

Related

Postman request with # character is not responding the proper output

I am trying to get on specific object of my model which has "#" in its name ex:obj#1 like this, but when I use this object to retrieve its related attribute I am getting error like below:
"error-message": "Request could not be completed because the relevant data model content does not exist"
can you please suggest me any way to request my object in postman?
Do you use "#" in the URL? It is a reserved character and needs to be encoded.
Here you can see the reserved URL characters and how to encode them:
https://en.wikipedia.org/wiki/Percent-encoding

Handle hash (#) in query string

I try create simple OAuthHandler.
After my request (using the implicit flow), server send request to my page, with an authorization code. But in query string from server, all parameters starts with hash (#) instead?
In method HandleRemoteAuthenticateAsync, I'm trying to parse query string, but none of the properties contain authorization code or anything like that.
How can I handle hash in query string?
As Joppe and David mentioned in the comments, anything after the hash (#) is part of the fragment, and is not sent to the server by the browser. That's why your server code can't see it.
The implicit flow is for JavaScript clients, not web servers. You want the authorization code flow instead. The redirect will look like:
REDIRECT_URI?code=7a6fa...
Since the code is transmitted in the query string, instead of the fragment, your server-side code will be able to see it.

Get current fragment in Route, ASP.net MVC

Is there away to get the current fragment from a route that was issued via action link. This is how I am getting the action from the route.
string currentAction = requestContext.RouteData.Values["action"] as string ?? "index";
Can I do something similar to this?
string currentFragment = requestContext.RouteData.Values["Fragment"] as string ?? "";
No, you can't do anything like this. The fragment (everything that follows the # sign in an url) is never sent to the server by the browser, so the sole fact of talking about getting the url fragment server side simply doesn't make sense.
So if you have the following url: http://example.com/foo/bar?key1=value1#abc the server will never be able to fetch abc simply because the client will never send it.
As it has already been pointed out that is not possible. Document fragments (the string after the hash as you call it) are intended for the browsers only to correctly position the viewport. They have no meaning for the server and therefore are not transmitted there.
There is however a workaround you can use. Repeat the fragment as part of your url to make it accessible for the server.
Look at the permalink to the answers in this question. For instance, the link to my answer looks like this:
http://stackoverflow.com/questions
/6285833/get-current-fragment-in-route-asp-net-mvc/6286097#6286097
See how the value 6286097 is duplicated as the last route parameter. It's intentional. You can use this technique as well.
P.S. The fragment must point to an identifier in the document (id of some HTML element). At least in XHTML only identifiers work as fragments. Valid ids may not begin with a digit therefore instead of #6286097 use something like #answer-6286097.
P.S.#2. Do not use any JavaScript trickery to get around this limitation. Basic site functionality and design must work without JavaScript - don't listen to anyone who tells you otherwise. Fragments obviously belong to the basic tool box. Use JavaScript only for advanced interactivity.
I have a workaround for you, but first of all lets get more into the problem.
The strings after the hash symbol which are called Fragment values are not query parameters but they are strings to be read by the client-side (living in the browser) and the server cannot read them because they are not sent to the server by the browser.
Some authentication providers like Google and Azure send the access token as Fragment value for security reasons so that they are not transferred over the internet after they get sent as direct response from the authentication provider.
The only way you can come around that is to use javascript to convert the fragment values to query parameters by replacing the '#' with '?' and redirecting to the endpoint in your server controller.
I suppose the easiest way is to handle all that from server, meaning you get get the request in server, send a javascript code to the browser on the fly, that replaces the '#' into '?' and redirects to your second endpoint which reads the token as strong parameter.
Here how you can do it in ASP.NET Core 3.1:
[AllowAnonymous]
[HttpGet("authredirect")]
[Produces("text/html")]
public virtual ContentResult ConvertUrlFragmentToQueryParamThenRedirect()
{
return Content("<html><script>window.location.href=window.location.href.replace('#', '?').replace('authredirect', 'authparams')</script></html>", "text/html");
}
[AllowAnonymous]
[HttpGet("authparams")]
public virtual void GetAccessToken([FromQuery] string access_token)
{
// now you have your access token server side here
}
Please remember to set your redirectUrl to the correct one, in this case 'YOUR REDIRECT URL/authredirect'.

Extract string in url after # in Ruby on Rails

Due to my current implementation of using QR Codes, I cannot change the request url. I need to be able to parse an address to get the string after the hash sign, i.e.:
http://domain.com/#getthisstring
Is there a way to do this?
You cannot do this on the server side. URL fragment identifiers are not sent to the server.
You can however trap this value on the client side with JavaScript and send an Ajax request to the server passing the aforementioned value.
An impl in jQuery perchance?
$(function() {
$.post('someRailsEndpoint', {hash: document.location.hash});
});
On the Rails end, you'd use params[:hash] to access this value.

Do I need to encode strings (eg URL) I pass as a POST form parameter

Do I need to encode strings (eg URL) I pass as a POST form parameter?
Ie I want to pass a URL I have to my web application (ruby on rails) as one of the form parameters. So are there any potential characters in a URL/URI that would need to be encoded? Or perhaps rails would handle this anyway?
Do I need to encode strings (eg URL) I pass as a POST form parameter?
That depends on what you're using to create/send your POST request. If you're directly creating the request body yourself, then yes you would have to URL-encode each parameter:
POST / HTTP/1.1
Content-Type: application/x-www-form-urlencoded
foo=bar&url=http://www.example.com/url?innerparameter1=1&innerparameter2=2
this is no good:innerparameter2 is actually a parameter of the outer form-encoded string. It would need encoding, which would look like:
foo=bar&url=http%3A//www.example.com/url%3Finnerparameter1%3D1%26innerparameter2%3D2
If, however, you are using something higher-level to make the POST request, and passing in some kind of mapping of parameter strings, I would expect that component to take care of the URL-encoding for you.
Code?
As bobince mentions, you need to encode any data that you're passing as URL parameters. Often whatever library you're using will take care of this. This applies to all HTTP requests BTW.
For example, an API has an endpoint GET /sites/:name.
Using cURL it should look like
curl http://example.com/sites/google%2Ecom
In Ruby/Rails, you can use URI.encode and URI.decode:
>> URI.encode('google.com', /\W/)
"google%2Ecom"
>> URI.decode('google%2Ecom')
"google.com"
As a general statement, if you emit programmatic or user input data to an HTML page, you should encode it for HTML. Bear in mind that URLs often have the & character and that should be encoded, even if browsers appear to handle it okay.
I'm not a Ruby guy, so I don't know how you do that in Ruby, nor am I familiar with Ruby on Rails to say if it will do it (though I would be a little surprised by that), but the guideline I suggest isn't language specific.

Resources