POST Request with JSON Data in Javascript - javascript

I've been trying to send a JSON payload through a JS script but my webhooks seem unable to see the payload whatever I write.
Here is the code I put together from various online sources:
let xhr = new XMLHttpRequest();
xhr.open("POST","https://webhook.site/4530328b-fc68-404a-9427-3f2ccd853066/",true);
xhr.setRequestHeader("Content-Type", "application/json");
let data = JSON.stringify({'eventType' : 'test'});
xhr.send(data);
I'm not a JS developer but it seems to me that this should work. However every time I run this snippet the POST URL does not show anything back :/
Any idea why that is over here :) ?
Thank you for your time!

In your example, the webhook.site service you're attempting to connect to with your JavaScript isn't enabled (by default) with the proper CORS headers that modern browsers respect & enforce to improve user security. The developer console in your browser of choice should point this out to you; the error mine gave back was:
Access to XMLHttpRequest at 'https://webhook.site/5c7a5049-9c5e-4bf7-b1cf-0e05f6503bfa' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
As the error states, the requested resource doesn't respond with any valid Access-Control-Allow-Origin header, which will prevent the POST itself from being fully executed. In webhook.site, you can select the CORS Headers tickbox from the top of the user interface to enable the service to send the proper CORS headers to get this working.
let xhr = new XMLHttpRequest();
xhr.open("POST","https://webhook.site/5c7a5049-9c5e-4bf7-b1cf-0e05f6503bfa",true); // configuration interface at https://webhook.site/#!/5c7a5049-9c5e-4bf7-b1cf-0e05f6503bfa/e14fc471-4bc4-410f-b16a-0755a231fb12/1
xhr.setRequestHeader("Content-Type", "application/json");
let data = JSON.stringify({'eventType' : 'test'});
xhr.send(data);

I suggest you to use axios, it gonna be something like this and you will get the response from your post request
const response = await axios.post('https://webhook.site/4530328b-fc68-404a-9427-3f2ccd853066/', {'eventType' : 'test'});

Related

Discord Webhook Access-Control-Allow-Origin

I am sending a Discord webhook request using Javascript, but I keep getting the following errror:
Access to XMLHttpRequest at
'WEBHOOK URL'
from origin 'http://discordfastlist.ml' has been blocked by CORS
policy: Response to preflight request doesn't pass access control
check: No 'Access-Control-Allow-Origin' header is present on the
requested resource.
I know exactly what this is after googling alot, tried all the solutions I found but nothing seemed to work with Discord webhooks.
The code I am using:
var xhr = new XMLHttpRequest();
xhr.open("POST", "this is the webhook URL, I am not showing this in the code but it is there", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
'content': "test",
'username':'Test Webhook',
}));
You need to be able to negotiate the CORS policy with discord before hand, I think this person had the same trouble with a similar situation. Javascript CORS - No 'Access-Control-Allow-Origin' header is present
What you really need to do is perform the pre flight responses and attach the correct cors-policy to your request as well from your javascript request

Curl rest API to a second site in Javascript

I am trying to display a result from a rest API GET request, for example, "http://ifconfig.co/ip/" on my page. However, I am running into many different errors, and just cannot seem to get it down.
Her is what I have so far:
var req = new XMLHttpRequest();
req.open('GET', 'https://ifconfig.co/ip', true);
req.withCredentials = false;
req.setRequestHeader( 'Access-Control-Allow-Origin', '*' );
req.send();
document.write(req);
document.write(req.responseText);
document.write(req.responseXML);
In the javascript console it says "XMLHttpRequest cannot load https://ifconfig.co/ip. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
I am very new to javascript, can anyone point me in the right direction?
The No Access-Control-Allow-Origin message means that the server is configured not to accept requests from the client's domain. Here's a great article on MDN https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

How to set the Access-Control-Allow-Origin to "*" using XMLHttpRequest object?

I am trying to send a request to my api deployed in Heroku. I used an XMLHttpRequest object to fire a request to the api. I am trying out a simple
GET and no tricks. However, I receive this error:
XMLHttpRequest cannot load https://xxx-xxxx-xx.herokuapp.com/api/foods/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Which is normal for Chrome. However, I wanted to do this the way Postman handles it. How should I make the request to the api so that it allows everything?
I used this Chrome extension and it worked.
https://github.com/vitvad/Access-Control-Allow-Origin/
What I was able to figure out that it is basically setting this rule:
rule = {
"name": "Access-Control-Allow-Origin",
"value": "*"
};
However, when I try to set it using xhr.setRequestHeader() method, it doesn't work.
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://xxx-xxxx-xx.herokuapp.com/api/foods/', true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onload = function(){
console.log(xhr)
}
xhr.send(null);
</script>
It is your API in Heroku that needs to set the header, not the web client calling it.
Your browser is following the same origin policy by not allowing your page to request a resource in another domain. Your server can use CORS to let the browser know it is ok to make a request from another domain to this particular resource, but this information needs to come from your server.
The extension and Postman are not following the same origin policy like the browser is doing. The browser needs to follow this policy for your security.
How you set those headers really depends on how you implemented your endpoint in Heroku.

Why does the browser allow xorigin POST but not PUT?

Consider the very simple example of using XMLHttpRequest.
The following posts properly ( you can see it in the network tab or by directing your browser to http://requestb.in/yckncpyc) although it prints a warning to the console
XMLHttpRequest cannot load http://requestb.in/yckncpyc. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
const method = "POST"
const req = new XMLHttpRequest()
req.open(method, 'http://requestb.in/yckncpyc')
req.send("foobar")
console.log("sent")
req.addEventListener('load', function() { console.log(req.status, req.response) })
Sure. I get that. What I don't get is why merely changing the verb used to a PUT results in something completely different. The request sent is an OPTIONS preflight request and prints
XMLHttpRequest cannot load http://requestb.in/yckncpyc. Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
const method = "PUT"
const req = new XMLHttpRequest()
req.open(method, 'http://requestb.in/yckncpyc')
req.send("foobar")
console.log("sent")
req.addEventListener('load', function() { console.log(req.status, req.response) })
Why does the browser* treat these differently? It seems like something that would be done for security but that really makes no sense since an attacker can always use a POST instead of a PUT.
So what is the logic here?
Tried this in Chrome 52, Safari 9.1.2
GET, HEAD, and POST requests (with a couple other restrictions) can be made cross-origin with no additional communication. The responses cannot be examined, but the requests are allowed.
Anything else requires a preflight request to check the headers from the target site to see whether the request would be allowed.
The reason for such a setup is that GET, HEAD, and POST were historically allowed from browsers as a natural part of HTML semantics. Tags for scripts and CSS and images do GET requests, and forms do POSTs. When the CORS stuff was introduced, therefore, those were allowed under the assumption that sites were no more vulnerable to simple requests like that in an XHR world then they were in the simpler non-XHR world.
So simple requests are allowed, and the browser looks at the response headers to decide whether the requesting code in the cross-origin page should be allowed to see the response content. For other requests, the browser first sends an OPTIONS request to check the CORS response headers. Only if that looks OK (that is, if the response headers contain the appropriate "yes that's OK" headers) will the XHR be allowed to proceed.

Cross domain post json without preflight

I am trying to post some json to a sharepoint url, as in this example. The example uses node, but I am trying to do it in the browser.
I tried it with fetch first:
fetch("https://outlook.office365.com/webhook/...",
{
method: 'POST',
headers: {
'Content-Type': 'application/json;'
},
body: JSON.stringify(this.groupCardBody()),
})
From that i got the error:
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:1234' 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.
But i don't have control over the response, and if i add mode: 'no-cors' into the fetch options as it suggests, it strips the content-type header and returns 415 Unsupported Media Type.
So i tried it with a simple xhttp request and that fails too as it does the preflight and doesn't get the right headers back:
let xhr = new XMLHttpRequest()
xhr.open("POST", "https://outlook.office365.com/webhook/...");
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify(this.groupCardBody()));
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
The request library used in the example was quite difficult to get working in the browser and by no means lightweight (added almost 2MB to my webpacked script), so any suggestions about how to get round this are welcome I am pretty stuck, all my searches turn up answers for fixing the server and i don't have that option.
UPDATE
As suggested in the accepted answer, I solved it by posting the json back to the server and making the post from there, got it working with something as simple as the following:
Client:
fetch("PostGroupCard?json="+
encodeURI(JSON.stringify(this.groupCardBody())),
{credentials: "same-origin"}
)
Server:
Function PostGroupCard(json As String)
Dim wr = WebRequest.Create("https://outlook.office365.com/webhook/...")
wr.ContentType = "application/json"
wr.Method = "POST"
Using sw = New StreamWriter(wr.GetRequestStream())
sw.Write(json)
sw.Flush()
sw.Close()
End Using
Dim r = wr.GetResponse()
Using sr = New StreamReader(r.GetResponseStream())
Dim result = sr.ReadToEnd()
End Using
End Sub
Most of this answer is taken from the comments.
For security reasons, you cannot make an XMLHTTPRequest unless you are on the same origin or CORS header from the other domain says you can. If this were possible, any site could preform malicious actions like hack you accounts.
Two alternatives to consider would be JSONP and having your server act as a proxy to access the other domain.

Categories

Resources