POST Request problems in JavaScript [duplicate] - javascript

This question already has answers here:
XMLHttpRequest cannot load XXX No 'Access-Control-Allow-Origin' header
(11 answers)
Closed 3 years ago.
I`m working on a project in JavaScript and basically what I want is to send a post request to my server in order to perform a login. So I do that as it fallows:
in Index.html
<input type="button" name="" value="Login" id="login" onclick=doLogin() onsubmit="return false">
and I have a user.js
function doLogin() {
let email = $('#emailLogin').val().trim();
if(email === ""){
email = null;
}
let password = $('#passwordLogin').val().trim();
if(password === ""){
password = null;
}
sendLoginRequest(email,password,getLoginSuccessHandler,getLoginErrorHandler);
}
function sendLoginRequest(email, password, successHandler, errHandler) {
localStorage.removeItem('auth');
localStorage.setItem('auth', btoa(email + ":" + password));
let data = {email: email, password: password};
jQuery.ajax({
type: 'POST',
url: getURL() + "user/login",
contentType: "application/json",
headers: { 'Authorization' : 'Basic ' + getAuth()
},
data: JSON.stringify(data),
dataType: "json",
accepts: "application/json",
success: function (data, status, jqXHR) {
successHandler(data);
},
error: function (jqXHR, message) {
errHandler(jqXHR.responseText.message);
}
});
}
So when I press the button the page will send an OPTIONS request not a POST request.
And in the console the message it printed like that:
HTTP403: FORBIDDEN - The server understood the request, but is refusing to fulfill it.
(XHR)OPTIONS - http://localhost:port/user/login

It's possible your server is throwing a CROSS Origin error, you need to enable CORS on your server by adding these flags in the response of your server.
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
//If you have some custom headers please add below
headers.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, {your-custom-header}");
If you quickly want to test your API & Login Flow you can use any of the plugins on chrome extention to allow CORS for you. However, this is not a permanent solution like the one given above.

Related

http basic authorization with Flask REST

I am developing a simple REST service in flask.
I have been trying to implement basic authorization.
Whilst, I can pass the username and password from the webpage using manual entry, I can't seem to read them from the header.
Here is my code:
On the server
def test():
if request.authorization and request.authorization.username == '***' and request.authorization.password == '***':
return "Authorized"
else:
return make_response('Authorization failed', 401, {'WWW-Authenticate': 'Basic realm ="Login Required"'})
On the client - using JavaScript
<script>
$(document).ready(function(){
$("#authButton").click(function(){
$.ajax({
xhrFields: {
withCredentials: true
},
headers: {
'Authorization': "Basic " + btoa("***:***")
},
url: "********:5001/",
type: 'GET',
success: function(){
console.log("success");
},
error: function (){
console.log("error");
},
});
});
});
</script
>
I have also tried the Javascript code without the xhr fields section, but for neither do I get anything returned at all.
If I don't send the headers from the client it works and simply asks for manual input of the username and password.
All I'm trying to do is authenticate from the header.
Any pointers would be very gratefully received.

Error sending AJAX POST request from local .html file to localhost:8080. CORS: "It does not have HTTP ok status."

I am getting an error when attempting to send a POST via AJAX from my own .html and .js files to localhost:8080. Upon submitting the request, the full error reads: "Access to XMLHttpRequest at 'http://localhost:8080/contact/new-message' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
CORS is already enabled on my browser, so access is automatically "Access-Control-Allow-Origin : *", so this is a different from that error.
Is there a way to include an "ok" status in the header? Or is the problem arising from elsewhere? Any help is greatly appreciated. Here are some code snippets:
My JavaScript, which runs as part of a form-submission:
function submitMessageAJAXCall(inputName, inputEmail, inputMessage, inputRegion) {
$.ajax({
type: 'POST',
url: 'http://localhost:8080/contact/new-message',
data: JSON.stringify({
rbName: inputName,
rbEmail: inputEmail,
rbMessageText: inputMessage,
rbRegionId: inputRegion
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
success: function() {
alert('Success!');
displayThankYouMessage();
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Unfortunately that message did not go through.');
}
});
}
The Java code which recieves it:
#PostMapping("/new-message")
private ResponseEntity<HttpStatus> addNewMessage(#RequestBody RBNewMessage rbNewMessage) {
//validate message in service layer
boolean isRequestValid = contactService.validateNewMessageRB(rbNewMessage);
//is message is good, save it; else, return an error
if (isRequestValid == true) {
//create a new message
ContactMessage message = new ContactMessage();
//set message fields
message.setMyName(rbNewMessage.getRbName());
message.setMyEmail(rbNewMessage.getRbEmail());
message.setMessageText(rbNewMessage.getRbMessageText());
LocalDateTime timeOfMessage = LocalDateTime.now();
LocalDateTime timeWithoutNano = timeOfMessage.withNano(0);
message.setTimeStamp(timeWithoutNano);
int regionId = rbNewMessage.getRbRegionId();
Region region = regionService.getRegionById(regionId);
message.setRegion(region);
ContactStatus cs = contactStatService.getStatusById(1);
message.setContactStatus(cs);
//save message
contactService.save(message);
//return success
return new ResponseEntity<>(HttpStatus.OK);
} else {
//return error
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
And this is an example of a Postman request that is successful:
{
"rbName": "John Johnson",
"rbEmail" : "JohnJohnson#Email.com",
"rbMessageText" : "Hello there, this is my message.",
"rbRegionId" : 5
}
Add #CrossOrigin annotation (import org.springframework.web.bind.annotation.CrossOrigin) to the top of the controller class that is handling the request.

jQuery ajaxs CORS request

I am calling jQuery ajax request, at CORS resourse. Backend works on nginx, and there set OPTIONS hook and response with allowed all domains, and all request types. But unfortunatly i am getting error calback. On Chrome Network console i saw 204 answer on OPTIONS request. And I have never seen my original POST request.
var email = $('#your_email').val();
var sendData = {
issue: {
description: "email:" + email,
category_id: 1
}
};
$.ajax({
url: "https://domen/issues.json",
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa("goodtry:goodtryq"));
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-type", "application/json")
},
data: JSON.stringify(sendData),
success: function (val) {
alert("Thanks you, we are going to contact you soon");
},
error: function (val) {
alert("Please check your internet connection");
}
});
So it is solved. I missed diagnostic message
Request header field Authorization is not allowed by Access-Control-Allow-Headers.
So helpful answer culd be found here:
https://stackoverflow.com/a/24556330/2835239

jQuery.ajax to $http

I used this function
jQuery.ajax({
type: 'POST',
url: urlSubmit,
timeout: 5000,
dataType: 'text',
data: {
date : dataDate,
url : dataUrl,
domaine : dataDomaine,
email : dataEmail,
destinataire : dataDestinataire,
msg : dataMsg
},
"success": function (jqXHR, textStatus, errorThrown) {
console.log("AJAX success :) - statut " + textStatus);
$timeout(successMailZR_alerte, 3000);
},
"error": function (jqXHR, textStatus, errorThrown) {
console.log("AJAX fail :/ - statut " + textStatus);
$timeout(errorMailZR_alerte, 3000);
}
});
Whats the code is doing : code POST to a php script who send an email.
but, since i rewrited my code in a complete angularjs app, i do it like this :
$http({
method: 'POST',
url: urlSubmit,
timeout: 5000,
cache: false,
data: {
date : dataDate,
url : dataUrl,
domaine : dataDomaine,
email : dataEmail,
destinataire : dataDestinataire,
msg : dataMsg
},
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
responseType: 'text',
}).
success(function(data, status, headers, config) {
console.log("AJAX success :) - statut " + status);
$timeout(successMailZR_alerte, 3000);
}).
error(function(data, status, headers, config) {
console.log("AJAX fail :/ - statut " + status);
$timeout(errorMailZR_alerte, 3000);
});
Problem is : with $http, i have a success 200 but nothing is posted and i have no return in my email. What's the problem ?
The problem is that jQuery's POST does send your data as form data (e.g. key-value pairs) (https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms/Sending_and_retrieving_form_data) whereas AngularJS sends your data in the request payload. For a difference between the two see the following SO question: What's the difference between "Request Payload" vs "Form Data" as seen in Chrome dev tools Network tab
In order to make your angular script works with your server you have to convert your data to a URL encoded string as described here: How can I post data as form data instead of a request payload?. Simply setting headers: {'Content-Type': 'application/x-www-form-urlencoded'} is not enough.
A different approach would be to adapt the back-end of your application to parse the message payload instead of the form data parameters.
To understand this one need to understand the request headers set by angular and jquery, There are differences with the headers like when request is post by jQuery then header might look like this:
POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded // default header set by jQuery
foo=bar&name=John
You can see this in form data in the request made in the browser, if you use chrome then you can see this in chrome inspector at network tab, if you click the request then you can see the form data and content headers set by the jQuery.
On the other side with angular js $http service, when a request is made then you can find these:
POST /some-path HTTP/1.1
Content-Type: application/json // default header set by angular
{ "foo" : "bar", "name" : "John" }
The real difference is this you have a request payload not usual form data which is used by jQuery. so you need to do something extra at the server side like below.
Use this:
$data = json_decode(file_get_contents("php://input"));
echo $data->date;
// and all other params you have sent
This is due to its default headers
Accept: application/json, text/plain, * / *
Content-Type: application/json
and jQuery unlikely have something else:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

How to avoid pop up login when calling WCF service from jquery ajax

Friends,
I know you have been facing these kind of question a lot.I was unable to find an answer even after a lot of google search.Well, lets come to the issue.
Requirement: Call a WCF Service GET API with basic authentication enabled using jquery ajax request.
Client side code:
<script src="Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="Scripts/Base64.js" type="text/javascript"></script>
<%--<script src="Scripts/jquery.base64.js" type="text/javascript"></script>--%>
<script type="text/javascript">
function make_base_auth(user, pass) {
var tok = user + ':' + pass;
var hash = Base64.encode(tok);
return "Basic " + hash;
}
$(document).ready(function () {
var username = 'user';
var password = 'ppp';
var auth = make_base_auth(username, password);
$.ajax({
type: "GET",
dataType: "jsonp",
contentType: "application/javascript",
xhrFields: {
withCredentials: true
},
cache: false,
crossDomain: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("Authentication", auth)
},
data: { 'inputData': "{PatientID:'12',FromDateTime:'05/21/2013 1:28:15 PM',ToDateTime:'05/21/2013 1:28:15 PM',ResponseType:'json',CompressResponse:'false'}" },
url:"http://192.168.15.160/RestAPI/Service.svc/GetMedicationValues",
success: function (jsonData) {
console.log(jsonData);
},
error: function (request, textStatus, errorThrown) {
console.log(request.responseText);
console.log(textStatus);
console.log(errorThrown);
}
});
});
</script>
Problem : I am getting login pop up when running the client application.I get the output only when i provide correct credentials on the pop up, irrespective of what credentials i pass in the request header.I have come through people asking this question a lot.Have anyone been able to solve this issue ? Thank You.
JSONP doesn't work with basic authentication.
If you don't need cross-domain request, use json as datatype.
Alos note that since JQuery 1.7, there are now two options for authentication : userName and password.
If the server performs HTTP authentication before providing a
response, the user name and password pair can be sent via the username
and password options.

Categories