jQuery .ajax PUT request not respecting custom header - javascript

I'm losing my custom header when using PUT type with .ajax. But, the header is fine with GET, but gets mangled with PUT. Please see evidence 1:
// GOOD GET:
$.ajax({
url: url,
type: 'GET',
dataType: 'json',
headers: {
Accept: "application/json"
}
});
// Actual header sent (using fiddler):
Accept: application/json
// BAD PUT:
$.ajax({
url: url,
type: 'PUT',
dataType: 'json',
headers: {
Accept: "application/json"
}
});
// Actual header sent (using fiddler):
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
As you can see the only difference is the value of type causing the value of the Accept part of the header gets trashed. jquery-1.8.2.js. Any thoughts? Thanks
Stabby

It seems it is browser related:
http://jsfiddle.net/oceog/WqXzA/
Request URL:http://fiddle.jshell.net/_display/
Request Method:PUT
Status Code:200 OK
Request Headersview source
Accept:application/json
Chrome 25.0

Related

Trying to Convert jQuery ajax to ES6 fetch

In an effort to not use jQuery (if ajax is all I need it for) I have the following ajax call that works like a champ.
$.ajax({
type: "POST",
url: "/Tests/EEG/Portable/Index?handler=Testing",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
data: JSON.stringify(model),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("Success");
},
failure: function (response) {
alert(response);
}
});
I rewrote it in standard javascript using fetch as follows:
fetch("/Tests/EEG/Portable/Index?handler=Testing", {
method: "POST",
headers: {
'XSRF-TOKEN': $('input:hidden[name="__RequestVerificationToken"]').val(),
'content-type': 'application/json; charset=utf-8'
},
body: JSON.stringify(model)
}).then(checkStatus)
.then(function (data) {
alert("second then");
}).catch(function (error) {
console.log(error);
});
Which gives me the following error:
Failed to load https://stubidp.sustainsys.com/xxx?SAMLRequest=xxx: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:58659' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Which leads me to add the following attribute:
mode: 'no-cors'
Which gives me the following warning (and does not get to my backed method)
Current.js:78 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://stubidp.sustainsys.com/xxx?SAMLRequest=xxx&RelayState=q-9E0I4hwfJLlInurXY-Yu4g with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.
Which lead me to add the following:
'X-Content-Type-Options': 'nosniff'
Which gave me the same warning and still did not get to my server.
Any thoughts on what I am still missing?
Update
While looking around the Network tab on Chrome's debugger tools, I noticed the Copy as fetch option. I did this on the working jQuery call and gave me the following JavaScript:
fetch("http://localhost:58659/Tests/EEG/Portable/Index?handler=Testing", {
"credentials": "include",
"headers": {},
"referrer": "http://localhost:58659/Tests/EEG/Portable",
"referrerPolicy": "no-referrer-when-downgrade",
"body": JSON.stringify(model),
"method": "POST",
"mode": "cors"
});
When I run that fetch method I get a 400 Bad request error.
I would say that thanks to #Wesley Coetzee that got the ball rolling in the right direction. What took care of it for me was the following code:
fetch('/api/Tests/Single', {
credentials: 'include',
headers: {
'XSRF-TOKEN': $('input:hidden[name="__RequestVerificationToken"]').val(),
'content-type': 'application/json; charset=utf-8',
'X-Content-Type-Options': 'nosniff'
},
referrer: '/Tests/EEG/Portable',
referrerPolicy: 'no-referrer-when-downgrade',
body: JSON.stringify(model),
method: 'POST',
mode: 'cors'
});
A little back story in case that helps: Everything in the question was based on trying to POST to an ASP.Net Core RazorPage event. After some realization between this new project we are starting and the extra pain you have to go through (not the above code) to convert a response to an actual entity, we changed to using WebAPI. The code in this answer is going to a WebAPI controller and no longer a RazorPage method.
Hope it helps someone.

Access MailChimp API 3.0 (GET)

I'm trying to make a GET request through jQuery to the Mailchimp API. It seems though my custom header is not correctly set as I get a Your request did not include an API key. error.
It works fine if I make the request using curl on my Ubuntu machine:
curl --header "Authorization: apikey 709XXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us11" https://us11.api.mailchimp.com/3.0/campaigns
Here's my code:
$.ajax({
type: 'GET',
url: 'https://us11.api.mailchimp.com/3.0/campaigns',
crossDomain: true,
dataType: 'jsonp',
contentType: "application/json; charset=utf-8",
headers: {
'Authorization': 'apikey 709XXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us11'
}
}).done(function (response) {
console.log(response); // verbose
});
I even tried adding this above:
$.ajaxSetup({
headers: { 'Authorization': 'apikey 709XXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us11' }
});
You need to add the key via Basic Auth like and as far I am aware off, You can't query it from front-end, it must be on the back-end.
Find an example in NodeJS:
headers: {
'Authorization': 'Basic ' + new Buffer(`anything:${MailChimpKey}`).toString('base64');
}
MailChimp not allowed to direct access with ajax. Once make Server WebRequest. It will surely work.

jQuery .post is working but triggering .fail without any information

I've got my data posting successfully but I'm not having any luck getting my .post response handler code to work. I get inconsistent results in the different browsers/tools I've tried. Here's the post code:
$.post(form.attr("action"), form.serialize(), "json")
.done(function (response, textStatus, jqXHR) {
alert('done');
})
.fail(function (jqXHR, textStatus, errorThrown) {
// log the error to the console
alert('responsetext:' + jqXHR.responseText + ', status:' + textStatus + ', error:' + errorThrown);
})
In FireFox and Chrome it always goes to the .fail (even though the data is successfully posting) but the only item set is textStatus to "error". In Firefox when I try to view the response it just shows the Error, "SyntaxError: JSON.parse: unexpected end of data at line 1 column 1". In Chrome, in the Console I'm seeing this: "XMLHttpRequest cannot load http://example.net/applicationsvc/formprocessor/index.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.net' is therefore not allowed access." Which seems very relevant but my attempts to solve it haven't worked.
How can I resolve the Access-Control-Allow-Origin issue in a .post? Why aren't I getting any error data and why is FireFox unable to parse the response.
Using PostMan, and using the same headers and body, I do see I'm getting a response of:
{"successful":true,"thankyou_message":"<h2>Thank you!<\/h2><p>Thank you for signing up!<\/p>"}
But the code doesn't seem to be getting or handling that.
Here are the Request headers that are going out:
Host: example.net
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://example.net/mypage.htm
Content-Length: 655
Origin: http://example.net
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
UPDATE:
I've now switched from the .post to .ajax
$.ajax({
url: form.attr("action"),
type: "POST",
data: form.serialize(),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function () {
alert('done');
}
});
With that I get a consistent HTTP 501 Response.
try to enable cross-origin on the server, example in php
header("Access-Control-Allow-Origin: *");
the server must send this in the response header, change the star accordingly to your domain for security reasons.
If you are using cross domain then try with the JSONP instea
Your Code
$.ajax({
url: form.attr("action"),
method: "POST",
headers: {"Access-Control-Allow-Origin":"*"},
data: form.serialize(),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function () {
alert('done');
}
});
Change it to
$.ajax({
url: form.attr("action"),
type: "POST",
headers: {"Access-Control-Allow-Origin":"*"},
data: form.serialize(),
dataType: "jsonp",
contentType: "application/json; charset=utf-8",
success: function () {
alert('done');
}
});

How can I specify xhr request with node.js + cheerio?

The page I'm scrapping is detecting whether the request is ajax or simple one. How can I specify that ?
app.get('/gsb', function(res, req){
request({
method: 'POST',
url: "https://www.somesite.com/somepage/"
} ...
Now, this somepage detects whether its xhr or not.
Thanks
AJAX is typically indicated via the X-Requested-With header in the request.
request({
method: 'POST',
headers: {'X-Requested-With': 'XMLHttpRequest'},
url: ...})
Try that and see if it does the trick.

How to make a jsonp POST request that specifies contentType with jQuery?

I need to make a jsonp POST request with the content type 'application/json'. I can get the POST request to the server like this:
jQuery.ajax({
type: 'POST',
url: url,
data: data,
success: success,
error: error,
async: true,
complete: complete,
timeout: TIMEOUT,
scriptCharset: 'UTF-8',
dataType: 'jsonp',
jsonp: '_jsonp',
});
But as soon as I add the line:contentType: "application/json" it starts sending it as an OPTIONS request rather than a POST.
How can I specify the content type and still submit the request as a POST?
It is not possible to make a JSONP POST request.
JSONP works by creating a <script> tag that executes Javascript from a different domain; it is not possible to send a POST request using a <script> tag.
Use json in dataType and send like this:
$.ajax({
url: "your url which return json",
type: "POST",
crossDomain: true,
data: data,
dataType: "json",
success:function(result){
alert(JSON.stringify(result));
},
error:function(xhr,status,error){
alert(status);
}
});
and put this lines in your server side file:
if PHP:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');
if java:
response.addHeader( "Access-Control-Allow-Origin", "*" );
response.addHeader( "Access-Control-Allow-Methods", "POST" );
response.addHeader( "Access-Control-Max-Age", "1000" );
There's a (hack) solution I've did it many times, you'll be able to Post with JsonP.
(You'll be able to Post Form, bigger than 2000 char than you can use by GET)
Client application Javascript
$.ajax({
type: "POST", // you request will be a post request
data: postData, // javascript object with all my params
url: COMAPIURL, // my backoffice comunication api url
dataType: "jsonp", // datatype can be json or jsonp
success: function(result){
console.dir(result);
}
});
JAVA:
response.addHeader( "Access-Control-Allow-Origin", "*" ); // open your api to any client
response.addHeader( "Access-Control-Allow-Methods", "POST" ); // a allow post
response.addHeader( "Access-Control-Max-Age", "1000" ); // time from request to response before timeout
PHP:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: 1000');
Doing like this, you are opening your server to any post request, you should re-secure this by providing ident or something else.
With this method, you could also change the request type from jsonp to json, both work, just set the right response content type
jsonp
response.setContentType( "text/javascript; charset=utf-8" );
json
response.setContentType( "application/json; charset=utf-8" );
Please not that you're server will no more respect the SOP (same origin policy), but who cares ?

Categories

Resources