JavaScript XMLHttpRequest with credentials to ASP.NET API - javascript

I am trying to do a post request withCredentials = true, but I get a CORS error on the console after sending the request.
This is the Controller I am trying to reach:
[RoutePrefix("Account")]
public class AccountController : ApiController;
This is the Action I am trying to reach:
[HttpPost]
[Route("Login")]
public IHttpActionResult Login(LoginDto dto);
I have added this line in WebApiConfig:
config.EnableCors(new EnableCorsAttribute("http://localhost", "*", "*"));
And here is what I use to do Post Requests with Javascript
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
if (xhr.withCredentials != undefined) {
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
function post(url, data) {
return new Promise(
function httpPromise (resolve, reject) {
var request = createCORSRequest("post", url);
if (request) {
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Content-Type', 'application/json');
request.onloadend = function (progress) {
var status = request.status;
var result = JSON.parse(request.response || "null");
if (status >= 200 && status < 300) resolve(result);
else reject(result ? result.Message || result : result);
};
request.send(data);
}
});
}
Below is the Error Message that appears in the console.
XMLHttpRequest cannot load http://localhost:54368/Account/Login. Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://localhost' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

You need to give specify SupportsCredentials = true in your config.EnableCors(…) call:
config.EnableCors(new EnableCorsAttribute("http://localhost", "*", "*")
{ SupportsCredentials = true });

Related

Request to IP camera Javascript

i'm trying to make a request into an IP camera, but the camera needs Basic authentication, i need to get this request and show in an Iframe or img, but i don't know how to get that, i see how the request to the camera stays always waiting to finish an send some data, but i don't know how to get it and pass to the Iframe, thank's for any help.
Code Example:
function makeRequest(method, url, data) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader(
"Authorization",
"Basic " + btoa("user:password")
);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText,
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText,
});
};
if (method == "POST" && data) {
xhr.send(data);
} else {
xhr.send();
}
});
}
//GET example
makeRequest("GET", "http://ip_camera_url").then(
function (data) {
var results = JSON.parse(data);
console.log(results);//Never come here
}
);
UPDATE:
First the request return status 200
then keeps sending data
but the request never ends and i can't get the result or the images the ip camera returns.
this is the message in the tab timing into the network option.

How I do use oauth in the reddit api in browser?

Nothing I do works, and I keep getting ridiculous CORS errors and other things. I just want to do a normal oath to log a user in, through the browser. I want to use snoowrap, but I can't even get far enough to use it, because i need a refresh token.
I already authorize the app and get the 'code' back from the API, which im then supposed to use by making a post request to https://www.reddit.com/api/v1/access_token.
But I just get CORS errors every time.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.reddit.com/api/v1/access_token. (Reason: missing token ‘access-control-allow-headers’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.reddit.com/api/v1/access_token. (Reason: CORS request did not succeed).
code:
const redirect_uri = 'https://EXAMPLE.com/reddit/';
const client_id = 'xxxxxxxxxxxxx';
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); /*global URLSearchParams*/
const code = urlParams.get('code');
var snoowrap = window.snoowrap;
if (code) {
console.log('code gotten', code);
const data = {
grant_type: 'authorization_code',
code: code,
redirect_uri: redirect_uri
};
ajax('https://www.reddit.com/api/v1/access_token', data, 'Basic client_id:', result => {
console.log(result);
const r = new snoowrap({
userAgent: 'skeddit',
clientId: client_id,
clientSecret: 'fFP-6BKjFtvYpIkgFGww-c6tPkM',
refreshToken: '',
});
r.getHot().map(post => post.title).then(console.log);
});
}
//GET: ajax(String url, Function success)
//POST: ajax(String url, Object postData, Function success)
function ajax(url, arg2, arg3, arg4) {
if (typeof arg2 == 'function')
var success = arg2;
else {
var postData = arg2;
var headers = arg3;
var success = arg4;
}
console.log('AJAX - STARTING REQUEST', url)
//start new request
var xhttp = new XMLHttpRequest({mozSystem: true});
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
success(JSON.parse(this.response));
xhttp = null;
console.log('AJAX - COMPLETE', this.response);
}
};
if (postData) {
//post request
console.log('post data: ', postData);
var formData = new FormData();
for ( var key in postData ) {
formData.append(key, postData[key]);
}
xhttp.open("POST", url, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.setRequestHeader("Authorization", headers);
xhttp.send(formData);
}
else {
//get request
xhttp.open("GET", url, true);
xhttp.send();
}
return xhttp;
}
I don't even understand why something would prevent me from doing a POST request to a public api
After hours of searching I found a solution:
If you're creating a browser-only JS app (no server), you should select your app type as "installed app" (instead of "web app") in the reddit console.
Then you have to send an Authorization header whose value is your Client Id, as stated here reddit/wiki/OAuth2
const fd = new FormData();
fd.append("code", code);
fd.append("grant_type", "authorization_code");
fd.append("redirect_uri", "your_redirect_uri");
const r = await fetch("https://www.reddit.com/api/v1/access_token", {
headers: {
Authorization:
"Basic " + btoa(unescape(encodeURIComponent(CLIENT_ID + ":" + ""))),
},
method: "POST",
body: fd,
});

Making synchoronous XHR request with chrome.webRequest.onBeforeRequest

I'm looking to make a Chrome extension that hooks in to chrome.webRequest.onBeforeRequest to determine whether or not to block the current page request. As a result, I need to make a request to an API to determine it.
Is there a good way to make the checkUrl request synchronous to satisfy the requirements of chrome.webRequest.onBeforeRequest?
function checkUrl(url, callback) {
let api = 'http://localhost:9000/filter';
let data = {
url: url,
};
let json = JSON.stringify(data);
let xhr = new XMLHttpRequest();
xhr.open('POST', api, true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
xhr.setRequestHeader('X-Bark-Email', email);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.response);
}
}
xhr.send(json);
}
function onBeforeRequestHandler(details) {
let url = new URL(details.url);
console.log(details.type, ": ", url.host)
checkUrl(url, function(resp) {
let status = resp.status;
let redirectUrl = resp.redirect_url;
if (status == "allowed") {
return { cancel: false }; // <<<<< This doesn't work b/c of the callback
} else {
return { redirectUrl: redirectUrl };
}
});
}
chrome.webRequest.onBeforeRequest.addListener(onBeforeRequestHandler,
{
urls: ["<all_urls>"],
types: ["sub_frame", "main_frame", "xmlhttprequest"]
},
["blocking"]
);
I swapped:
xhr.open('POST', api, true);
for
xhr.open('POST', api, false);
and that makes the request synchronous. Then returned the result from the xhr request and use that inline:
return JSON.parse(xhr.response);

sending a cross-origin POST request to localhost in Javascript

I am trying to use an XMLHttpRequest to POST some data to a server (currently localhost, but will later be remote) and retrieve the response. I am using the Cross-origin-resource sharing method described here. However, I never receive the response data. The result is the same if I ignore the cross-origin issue and just send a normal XMLHttpRequest. I have verified using Postman that the URL sent is correct (JSON data is returned). Does anyone see what I am doing wrong here? Thanks very much!
// taken from StackOverflow
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
function sendRequest() {
var theUrl = "http://localhost:4567/myApi?input="
+ encodeURIComponent("some text input");
alert(theUrl); // verified this is correct using Postman
var request = createCORSRequest("POST", theUrl);
if (request){
request.onreadystatechange = function() {
console.log(request); // shows responseText empty
alert("http returned " + request.responseText);
};
request.send();
}
}
The console.logged request looks like:
XMLHttpRequest {}
onabort: null
onerror: null
onload: null
onloadend: null
onloadstart: null
onprogress: null
onreadystatechange: ()
ontimeout: null
readyState: 4
response: ""
responseText: ""
responseType: ""
responseURL: ""
responseXML: null
status: 0
statusText: ""
timeout: 0
upload: XMLHttpRequestUploadwithCredentials: false
__proto__: XMLHttpRequest

How to make a simple CORS request?

THE SITUATION:
I am making an app in AngularJs.
I need to make a CORS request to fetch data from an api on a different address.
On the api i output a very simple json, for test purpose:
[{"id":0,"name":"First"},{"id":1,"name":"Second"},{"id":2,"name":"Third"}]
I need to fetch these data and display on my app.
$HTTP CALL:
making the $http call i get the following error, because the api is on a different domain:
No 'Access-Control-Allow-Origin' header is present on the requested resource
CORS REQUEST - THE CODE:
// Create the XHR object.
$scope.createCORSRequest = function(method, url)
{
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr)
{
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
}
else if (typeof XDomainRequest != "undefined")
{
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
}
else
{
// CORS not supported.
xhr = null;
}
return xhr;
}
// Helper method to parse the title tag from the response.
$scope.getTitle = function(text)
{
return text.match('<title>(.*)?</title>')[1];
}
// Make the actual CORS request.
$scope.makeCorsRequest = function()
{
var url = 'http://DOMAIN.COM/main/json_export_test';
var xhr = $scope.createCORSRequest('GET', url);
console.log('----- xhr -----');
console.log(xhr);
if (!xhr)
{
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function()
{
var text = xhr.responseText;
var title = $scope.getTitle(text);
alert('Response from CORS request to ' + url + ': ' + title);
};
xhr.onerror = function()
{
alert('Woops, there was an error making the request.');
};
xhr.send();
}
When i run the function makeCorsRequest i get the alert called by xhr.onerror
But i have no clues why it isn't working.
THE API:
This is the very simple php function in the api, for test purpose:
public function json_export_test()
{
$data = array(
array(
"id" => 0,
"name" => "First"
),
array(
"id" => 1,
"name" => "Second"
),
array(
"id" => 2,
"name" => "Third"
)
);
echo json_encode($data);
}
THE QUESTION:
How can i make a simple CORS request?
EDIT - THE SOLUTION:
This is how it looks the api after having edited it, thanks to the reply:
public function json_export_test()
{
header('Access-Control-Allow-Origin: *');
$data = array(
array(
"id" => 0,
"name" => "First"
),
array(
"id" => 1,
"name" => "Second"
),
array(
"id" => 2,
"name" => "Third"
)
);
echo json_encode($data);
}
In general: You just make a normal request using XMLHttpRequest. The browser will handle the rest. (The exception is in old browsers which either don't support CORS or which require you to use XDomainRequest instead of XMLHttpRequest — but you seem to be accounting for that already).
The error message you are getting indicates that you are not getting a CORS response, so the browser doesn't have permission to give the other site's data to your JavaScript.
You need to include Access-Control-Allow-Origin: * (or something more specific) in the HTTP response to the cross-origin request.

Categories