how to fetch the data from request body in anguar2 - javascript

i have created one URL and given to the end-user so when user hit my URL from other module i want to fetch the the data from the request body and and after fetching the data i am passing these data to my service and then validating and getting the response from my service.
but when user click on my URL and passing the data in URL then
I am able to fetch the data from URL like this
ngOnInit() {
this.route.params
.subscribe((params : Params) => {
this.email=params['id'];
});
but I am not able to fetch the data from request body when the user hit my URL so that i can fetch the data from the body and pass it to my service.
I need to fetch the two parameters from the request body.

Please first understand that the code you show is not a request to an api so there is no body.
All you are doing here is looking at the current route that shows in the address bar (ie. the current page of your angular app). There is no request body to fetch data from, only the query string params you can see in the address bar.
In other words, this.route refers to the CURRENT route of your angular app showing in the browser.
If you want to call an API and get data then you need to create a service to do that. For example:
#Injectable()
export class StoriesService {
constructor(private http:Http,private constService :ConstantsService) { }
public getStories()
{
this.http
.get(this.constService.apiBaseUrl + "/Stories")
.subscribe ((data: Response) => console.log(data));
}
}
In this example data is the request body returned by the call to [apiBaseUrl]/stories.
I would advise reading this tutorial.

Related

GET request working through Postman but the browser tells me GET request cannot have body

I'm simply trying to send some urlencoded parameters via a GET request using fetch. I'm just trying to print the parameters using Express at the moment, like so:
app.get('/api', function (req, res) {
console.log(req.body);
res.sendStatus(200);
return;
});
This works just fine in Postman using a GET request and x-www-form-urlencoded key-value pairs. The webserver will print all the key-value pairs just fine.
But when I try and use fetch to do the exact same thing I get nothing but problems. I've tried two different methods:
fetch(`http://localhost:3000/api?user=test&password=123`, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
The request does go through using this method, but the webserver only prints {} - an empty object.
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("user", "test");
urlencoded.append("password", "123");
var requestOptions = {
method: 'GET',
headers: myHeaders,
body: urlencoded,
};
fetch("localhost:3000/api", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
The request does not go through using this method, and the browser gives me the error TypeError: Window.fetch: HEAD or GET Request cannot have a body.
This code was generated using the request that works in Postman using the generate code snippets option.
What am I doing wrong?
The parameters in this URL:
http://localhost:3000/api?user=test&password=123
are in the query string, not in the body and thus the content-type does not apply to them - they are properly encoded to be in a URL. In Express, you would access these with req.query. You should see a value for req.query.user and req.query.password in your Exprss request handler.
Note, it is not recommended that you send user credentials in a URL like this because URLs are often present in log files at your ISP, at the recipient server, in proxies, in your browser history, etc... User credentials like this should be sent in POST request over https where the credentials would go encoded in the body (where it won't be logged or saved by intermediaries).
The fetch error is accurate. GET requests do not have a body sent with them. That would be for POST or PUT requests. A GET request is a "get" request for a resource that you specify only with a URL.
You're confusing request body with a query string.
Your second request (you don't need a Content-Type for it)
fetch("http://localhost:3000/api?user=test&password=123");
would be handled by the following Express function:
app.get('/api', function (req, res) {
console.log(req.query); // Note that query, not body is used.
res.sendStatus(200);
return;
});
You can access fields from the query object as req.query.user && req.query.password.
As for having a request body in a GET request: while RFC doesn't explicitly fordbid it, it requires server to not change response based on the contents of the body, i.e. the body in GET has no meaning in the standard, so JS HTTP APIs (both fetch & XmlHttpRequest) deny it.
firstly if you are trying to get some data from your API or others API you should do GET request in order to get your desired data from server for example, if you want to get a specific things like a user or something else you can pass your data in GET request URL using query string or route params.
secondly, if you want to authenticate and send your credentials to the server its not recommended to use GET request as i said earlier GET request simply is for fetching some data from server, so if you want to send your credential or anything else you are better off using POST request to send data to the server and you can't do POST request in the browser, so you have to use something like postman or insomnia in order to send your POST request to the server. i hope it could help you to solve your issue.

Detect form submission on a page

I have a vue app that sits behind a firewall, which controls user authentication. The only way that I have of detecting when the user needs to re-authenticate is when the axios requests sent by my app receive a 403 error. When this happens the server also returns a web page, which I see as, error.response.data. This page asks the user to re-authenticate via an embedded form that, when completed, authenticates the user and sends back the output from my app's original request.
My questions is how can I get the user to re-authenticate and then capture the data from my request that is returned? I can send the user the authentication page, for example by using:
var login_window = window.open('about:blank', '_blank');
login_window.document.write(error.response.data)
login_window.focus()
but then I don't see how to determine when the user has authenticated. When this happens, login_window.document.body.innerText contains the json data from my app's request, which my apps needs but which I don't want to show to the user. When doing this "by hand", I also have not succeeded in extracting the json from login_window.document.body.innerText as the json structure has been stripped and it now looks something like this:
JSON
Raw Data
Headers
Save
Copy
Collapse All
Expand All
status \"OK\"
message \"\"
user \"andrew\"
This question tries to reduce my previous question down to a javascript problem. There may be a better way to do what I want using axios; see Handling an authentication page returned by an axios request in vue for more details.
One solution is to override the <form>'s submit-event handler, and then use XMLHttpRequest to submit the form, which gives you access to the form's response data and status code. A status code of 200 implies that the user is authenticated, and the response data should contain the response of the original request before authentication.
Steps:
Query the form's container for the <form> element:
const form = document.querySelector('#container > form').querySelector('form')
Add a submit-event handler that calls Event.preventDefault() to stop the submission:
form.addEventListener('submit', e => {
e.preventDefault()
})
Use XHR to send the original request, adding your own response handler to get the resulting data:
form.addEventListener('submit', e => {
e.preventDefault()
const xhr = new XMLHttpRequest()
xhr.addEventListener('load', e => {
const { response } = e.target
const data = JSON.parse(response)
// data now contains the response of the original request before authentication
})
xhr.open(form.method, form.action)
xhr.send(new FormData(form))
})
demo

HTTP Basic Authentication GET request in AngularJS

I have one GET endpoint.
It has HTTP Basic Authentication enabled. I want to create a GET request to the given end point.
https://example.com/api GET
User Name :- admin
Password :- admin
My Code :-
$scope.listData = function() {
$http.get('https://example.com/api').then(function(response) {
$scope.items = response.data;
});
}
What is the recommended way to pass the authentication?
Second argument for the GET is the header part. For ex.
$http.get('www.google.com/someapi', {
headers: {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}).then()..;
the recommended method is http-interceptors.
what interceptor do, you can assume its a hook which call on every api request and response, once you write it, it will automatically add token in every api request. below is the url you read the article.
Angular Authentication: Using the Http Client and Http Interceptors

nodejs express res.render in ajax calls

i have a problem with res.render() in expressjs
i use ajax to request on this route:
route.get('/about',authentication,(req,res)=>{
res.render('about');
});
I did some search and found out that res.render does not work with ajax calls
so how can I change and render page without res.render().
If I remove the res.render and console.log it it will work actually any code work but not res.render (by clicking a link I send a token in header with ajax request then in my route I have an authentication middleware that get the token then redirects the user to about.ejs page)
I just want to change the page. Any idea will help guys.
thx
here is the front-end request:
$(document).ready(function(){
$('#about').click(function(){
// window.location.href='/about';
$.ajax({
method:'get',
url:'http://localhost:5000/about',
headers:{"authtoken":localStorage.getItem('authToken')}
}).done(()=>{
// window.location.href='/about';
}).catch(e=>console.log('header.ejs error'));
});
});
res.render composes a html page using templates and sends the final composed result from the server to the client. It does not issue a rendering of the page in the client window.
If the request is issued by entering the URL in the addressbar of the browser, then the browser will do the request and render the result the server sends.
If you do an ajax request you will receive that response, but you are responsible to do something with it in the .done callback. The browser does not magically know what has to be done with the data if you do an ajax request. And because you do not have anything in your .done callback nothing will happen.
So you have to do something like that:
.done(response => {
var bodyContent = response.match(/<body>(.*)<\/body>/)[1]
$('body').html(bodyContent);
})
Usually ajax is used to update a portion of page using some resposne from server without refreshing page. If you want to navigate to another route instead of ajax use form submits or href. If you stick to ajax then return a JSON from the server and do the alteration using javascript
requestHandler=(req,res)=>{
res.json({data:{}})
}
Step-1: Make a public URL, say http://your-web-site.com/redirect_destination.html
Step-2: On making ajax request from front-end, redirect user to that page using .redirect() method on response
EDIT:
The point is, I don't think it's possible to render page by making an ajax request. You can prepare a URL which renders your desired page and redirect user to that URL using .redirect() method.
Your router will not render page ,it will send only response and I didnt get just for page rendering, why you are calling ajax request on click event.If dont mind you can write logic on click and change window.location with your router. It will render particular page, for that your router should be something like this:
// about page route (http://localhost:8080/about)
router.get('/about',isAuthenticated, function(req, res) {
res.sendFile(path.join(__dirname+'/public/about.html'));
});
function isAuthenticated(req, res, next) {
// do any checks you want to in here
// CHECK THE USER STORED IN SESSION FOR A CUSTOM VARIABLE
// you can do this however you want with whatever variables you set up
if (req.user.authenticated)
return next();
// IF A USER ISN'T LOGGED IN, THEN REDIRECT THEM SOMEWHERE
res.redirect('/');
}
And change your url on click to http://localhost:8080/about

Insert custom variable in $http post request header or body

In my project, I already have AngularJS service that inserts desired object using $http.post as follows:
function insertObject(object, callback) {
$http.post(apiUrl, object).success(function (data) {
"object" is set in corresponding AngularJS controller and sent to my service like:
objectServices.insertObject(object, function (data) {
According to this, "object" is sent through $http post request body. What I need, is to send one additional variable inside this $http request. Actually, this variable should be URL (route), with which the controller works.
I can't change this object structure (to attach new property to it, which would hold URL info etc.) because $http.post(apiUrl, object) matches corresponding backend API Controller method that takes exactly this object as parameter (this object is entity).
I tried something like this:
Declare variable that will hold URL info:
var url = window.location;
And attach it to $http.post header like:
$http.defaults.headers.common["currentUrl"]= url;
where "currentUrl" is supposed to be key and url is value.
Also tried something like:
$http.post(apiUrl, object, headers: { 'currentUrl': url })
and on backend side, inside corresponding API Controller HttpResponseMessage method tried to extract it from request header as:
Request.Headers.Single(x => x.Key == "currentUrl").ToString();
but it didn't work. Please, can someone explain how to send custom data inside http post request and tell me what wrong is with my try?
EDIT: Content of Request.Header on backend side is:
While attaching the variable:
$http.defaults.headers.post.currentUrl = url;
When making the call, you missed the braces:
$http.post(apiUrl, object, {headers: { 'currentUrl': url }})

Categories

Resources