I'm working on an application stack that has a rather particular architecture. The forms component is loaded on a view, and when the action is submitted, an async call using sidekiq is performed. This calls an endpoint that validates the form data, but none of this is returned back to the server and after this process is fired, there is a redirect to another page.
We want to add cookies to write the status of this call sidekiq did. This is not possible to do on the controller as the controller when it is rendering the destination page has no knowledge of this event that occurred. The possibility of writing this cookie on the async callback is tempting but this is not done on the controller (The controller loads a class that contains a module with this functionality)
Question: Is it possible to write cookies in places not in the controller, such as classes or models? I'm assuming no, but I figured it might be an interesting question.
It's not possible. Writing a cookie is a part of HTTP response, so you need to be in the request-response cycle, i.e. in the controller.
What you could do (and I did that more than once) is to have some kind of record in the database, storing a status of a background job, and from the page you redirected to periodically poll some endpoint with AJAX (or establish a Websocket connection) to check if the job has finished and with what status. Then you'll be able to set the cookie.
Related
I just started studying Ajax and I totally have not idea what AJAX is. What is the difference between asynchronous and synchronous request? I would like to seek a very simple example demonstrating their differences.
AJAX short for Asynchronous JavaScript And XML is a programming language. It typically involves sending HTTP requests from client to server and processing the server's response, without reloading the entire page. This process is asynchronous. Comparing to synchronous request which blocks the client until operation completes, asynchronous HTTP is more efficient and user-friendly.
Take very simple example, when you are signing up on a commercial website, you can know whether your username is available or not once you finish typing the name. If the username was used already, the website will give you a reminder that your username is used on the same web page. This is the application of AJAX, so you don't need to complete the whole form and click the submit button to know that your username is not available.
AJAX uses two components for request process and display:
A browser built-in XMLHttpRequest object (to request data from a web server)
JavaScript and HTML DOM (to display or use the data)
It begins with an event occurs in a web page, such as a button is clicked. Then an XMLHttpRequest object is created by JavaScript, followed by sending a request to a web server. Once the web server receives the request, it will process it and send a response back to the web page. Then the webpage utilizes JavaScript to perform update of the web page without reloading the whole page.
AJAX stands for Asynchronous JavaScript And XML
Ajax main purpose is the loading data from the server without refreshing the web page
It's works in the background thread without interrupting UI thread
AJAX allows web pages to be updated asynchronously by exchanging data with a web server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page.
A browser built-in XMLHttpRequest object which is used to request data from a web server
Example
when you are filling any kind of online form that time observe one thing there is option for country,state,district.
In this country drop down initially filled with data but state and district's are empty.
when you select a country like India then Asynchronous call goes to server and fetch the data of state drop down respective to selected country and so on.
when AJAX request fetching the data for the state drop down you are eligible to work with other parts of the form.
I was trying to pass data around between controllers all day long, but now I'm at the point where I think I haven't quite understood the basics.
Throughout the documentation of ASP .NET core, they use the word "request". I was under the assumption that this is the HttpRequest that is made by the client of the WebServer.
There are also different things that are supposed to be bound to the lifetime of a request:
The HttpContext and its HttpContext.Items dictionary.
Services added with AddScoped via dependency injection.
The TempData dictionary? (not so sure about that)
But when trying to pass data around, I made the observation that when I do return RedirectToAction(...); the HttpContext changes (HttpContext.GetHashCode() has a different value), TempData changes and services added via AddScoped are also new objects.
That would suggest that on RedirectToAction a new request is made, going through all the steps of the request pipeline again. My expectation though was that a RedirectToAction only continues the current request pipeline with a different controller action.
I also thought that the browser or whatever client only made one request and got one response during that entire process.
So what is actually happening when calling RedirectToAction in a controller action and returning the result?
UPDATE:
Using TempData works, but a TempDataProvider has to be configured first. For example add services.AddSingleton<ITempDataProvider,SessionStateTempDataProvider>(); to Startup.cs. Thanks #RonC.
As mentioned, RedirecToAction will cause the browser to make a new request, and when that new request comes in, it will create a totally new HttpContext. As mentioned, To pass data between the two requests, you can use the query string, session or cookies. But there is another option to consider.
TempData
Data can be passed from one request to another via the TempData collection which is accessible in the controller action method. The TempData collection was specifically designed for passing data from one request to another. The beauty of TempData is that the lifetime of an object placed in TempData is exactly one additional request. So anything placed in TempData in request 1 will be there for request 2 but then be automatically removed from TempData at the conclusion of request 2. This makes TempData perfect for passing data from one request to another without having to disclose that information in a query string or possibly forgetting it in session and bloating the session object.
It's impossible to save state of current request, because... HTTP is stateless. Every RedirectToAction really tells browser to make another HTTP request. As documentation says.
Returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action.
If you would like to pass some data between HTTP requests, you have to use cookies or session mechanism.
Is there a way that a MVC Action, initiated by an AJAX request, can redirect the response directly to another page/View without sending a JavaScript “window.location=…” to the client first? In other words, directly transferring the response on the server side and avoiding the roundtrip to the client.
This is a more general question about the possibility to transfer directly an AJAX call, but here is a more specific scenario:
The browser sends an AJAX request to the server and based on the request data the controller's logic performs some operations.
For the majority of the cases, the controller needs to return back a result (JSON) to the same page. However, for few cases it needs to redirect to another page and it returns back a script to redirect the page, but this causes another roundtrip to the browser. The flow is: Page – Server – Page – Server – New Page, and the question is if this can be optimized to Page – Server – New Page .
This isn't really possible, no.
The browser has two options to choose between:
Go to a page
Make an AJAX call to a page
It can't make an AJAX call and automatically redirect based on what the server decides because the client (browser) doesn't know what the server has decided on before the response is even received by the browser.
The traditional approach (which you're avoiding) is:
The browser makes an asynchronous request to the server
The server responds with data informing the client to redirect
The client makes a new request to the server via window.location
The server responds with the new page
However you want to skip a step by doing:
The browser makes an asynchronous request to the server
The client makes a new request to the server via window.location
The server responds with the new page
But the client doesn't know that it needs to redirect and/or it doesn't know how to.
One (ugly) possibility
One idea that comes to mind to pseudo-achieve what you want is to have MVC render the required view and send the whole thing back to the client via JSON rather than a redirection approach. Let me explain.
The browser makes an asynchronous request to the server
The server determines which page needs to be displayed and renders the view (Generating a view without a controller in MVC)
The server serialises the resulting HTML as JSON
The client receives the JSON, and re-renders the entire page with the new markup (i.e. completely replace)
You can also alter the URL and history of the browser to make it "feel" like a redirect by manipulating the browser history.
However I would like to point out that this "solution" is more of an amusing/interesting approach. This isn't really a good way to go about the problem.
To keep it simple I have a feedback form on my website. Whether or not the following is best practice is moot as I'm interested in the way this works. The customer can fill out their name, email address and reason for feedback on the form. This is then posted via AJAX to a server side function called SendFeedback. I am using .NET MVC4 and the SendFeedback method simply returns a true or false string. However I was testing out sending scripts through it to check out the security of the form and noticed that when I attempted to send through HTML tags or javascript that the SendFeedback method wasn't being invoked at all and instead my custom error page was being sent back to the client side AJAX response (if I sent though standard text, the SendFeedback method was being invoked as expected). Where is the first place that AJAX data is sent before it is passed into the server side method I am calling from the client? Is there any way to set a breakpoint here so I can examine what is going on?
This is part of an ASP.NET feature called request validaiton which is turned on by default. And which executes in ASP.NET handler before your code. If you desire, this feature can be turned off in web.config, but I would strongly advise against it.
More information on request validation can be found in MSDN.
I'm been reading up on Ajax and would like to see from the stackoverflow community if I'm understanding everything correctly.
So the normal client server interaction is a user pulls up a web browser types in a url and a HTTP request is sent to the server requesting the page and resources( css, pics ) from the web server. The web server responds to the client via HTTP the page/resources requested and the browser renders the html/JavaScript for the user to view the page.
1) So would it be safe to say that XMLHttpRequest( XHR ) object is doing the same process as the browser except your not requesting html from the server, your requesting text in some type of format?
2) Is it true that a XHR object is much like a regular object that can be manipulated by the program creating the object( like a normal object ), but also sends and receives data with another program( web server ) via HTTP?
3) So in my mind when a XHR is created it is loaded into memory and we setup some of the objects arguments when we do the request.open(“GET”, url, true). Once we do a request.send(null) the object basically attempts to “GET” the url via HTTP and once we get the data back from the server it is put in the responseText argument. Am I understanding this correctly?
4) Also synchronous vs asynchronous. When I think of synchronous I think of steps having to be followed in order. For example, I push a button, data gets sent to server, and I have to wait for data to come back before I can do anything else. With asynchronous connections I would push button, data gets sent to server, I do what ever I want while data gets sent back. Is this a good analogy?
1) Nope. The XMLHttpRequest object does exactly what its name implies -- it initiates an HTTP request. This request can be in XML, or HTML, or PHP. At the end of the day, the browser doesn't care, because in an AJAX request, it doesn't parse the request -- you have to do it yourself. So it doesn't automatically render the HTML from an AJAX request.
2) I'm not sure about manipulation (the XHR object may be immutable) but possibly. Would you ever need to extend it or manipulate it?
Yes, you can change properties of the object and so on. I apologize. I didn't understand you at first :)
3) Yep.
4) That's a great analogy. It's exactly what happens. Another analogy is a 4 lane highway is to asynchronous as a one-way street is to synchronous. If one car breaks down on the 4 lane highway, the rest can keep moving at their normal speed -- but if one breaks down on the one-way road, everything freezes. :)
Here I leave you a good graphic to see clearly the behavior differences between the synchronous and asynchronous application models:
(source: adaptivepath.com)
It would appear that you have a job grasp of how AJAX works. I can't see much to disagree with in your summary of the plumbing of an AJAX application.
I would say however that with the XMLHttpRequest object you aren't restricted to GET. You can also use POST and other HTTP verbs.
With async calls you register a callback function, the XMLHttpRequest object calls your method when the async request completes.
Seems ok to me.
Your first point though is not entirely correct, you can request html from the server using ajax is doesn't have to text, json or xml like most examples show.