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.
Related
I am attempting to write a method so that i pass the url and application name and it return the response. I read that I can apply callback to resolve this but I am not able to resolve the issue. Any help would be appreciated.
Please find below my code snippet.
var response = getResponse(url,applicationName)
console.log("response from getResponse \n" +response);
function getResponse(url,applicationName){
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
"application": applicationName
}));
xhr.onload = function() {
console.log(this.responseText);
}
return xhr.responseText;
}
You can use the onreadystatechange method to handle XHR responses, try this:
//XHR POST
const xhr = new XMLHttpRequest; // creates new object
const url = 'https://api-to-call.com/endpoint';
const data = JSON.stringify({"application": applicationName}); // converts data to a string
xhr.responseType = 'json';
xhr.onreadystatechange = () => {
if(xhr.readyState === XMLHttpRequest.DONE) {
return xhr.response;
}
}
xhr.open('POST', url); // opens request
xhr.send(data); // sends object
you should use promise instead of callback and do something like that.
const url = "https://httpbin.org/post";
const applicationName = "test";
getResponse(url, applicationName)
.then(response => {
//work here, not outside
console.log(response);
})
.catch(error => {
console.log(error);
})
function getResponse(url, applicationName) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({
"application": applicationName
}));
xhr.onload = function() {
// print JSON response
if (xhr.status >= 200 && xhr.status < 300) { // if valid
// work here
const response = JSON.parse(xhr.response.replace(/"/g, '"'));
const data = JSON.parse(response.data.replace(/"/g, '"'));
resolve(data);
}
reject(xhr.response); // reject and return the response if not valid
}
})
}
If you want to learn more about asynchronous https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Concepts, I invite you to go to this website to learn a little more about the promise.
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Promises
The callback is executed after the code returned xhr.responseText. So that means xhr.responseText returns null.
I would recommend using the fetch API opposed to the older XMLHttpRequest you are using now. The fetch API is basically a Promise based XMLHttpRequest.
Your function would look something like:
async function getResponse( url, applicationName ) {
const json = JSON.stringify({
"application": applicationName
});
return fetch( url, {method: 'POST', headers: { 'Content-Type':'application/json'}, body: json} );
}
// access like this
getResponse( url, applicationName)
.then( response => { console.log(response) });
async function someFunction( url, applicationName ) {
// or pause the code while the request is fetched by using await, note that you need to be in a function that is declared async to use this approach.
const response = await getResponse( url, applicationName );
}
Fetch documentation can be found at MDN: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
I use the following method to make AJAX requests:
function getJSON(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "json";
xhr.onload = function() {
if (xhr.status === 200) {
callback(null, xhr.response);
}
else {
/*var errorObj = { status: xhr.status, statusText: xhr.statusText };
callback(errorObj, xhr.response);*/
callback(xhr.status, xhr.response);
}
};
xhr.send();
};
I have to get the custom response text from the server if the status is 403. xhr.response is null, although I can see the custom error message in the Network tab of the Chromium debugger window. How can I access the custom response text?
try this :
if (xhr.status === 200) {
callback(null, xhr.response);
} else if(xhr.status === 403){
callback(xhr.status, "not found =(");
}
else {
/*var errorObj = { status: xhr.status, statusText: xhr.statusText };
callback(errorObj, xhr.response);*/
callback(xhr.status, xhr.response);
}
xhr.responseText should to the trick
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);
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 });
After I've Promisified my XMLHttpRequest, like so:
var Request = (function() {
var get = function(url){
return request('GET', url);
},
post = function(url){
return request('POST', url);
},
request = function(method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function(e){
if (xhr.status === 200) {
resolve(xhr);
} else {
reject(Error('XMLHttpRequest failed; error code:' + xhr.statusText));
}
},
xhr.onerror = reject;
xhr.send();
});
};
return {
get: get,
post: post,
request: request
}
})();
I'd like to catch all network related errors, which this snippet already does. Now, when I chain my .then calls when the XHR calls are finished, I can pass around the result of the Ajax call.
Here is my question:
When I throw an Error in any .then branch, it will not get caught by the catch clause.
How can I achieve this?
Note that the throw new Error("throw error"); will not be caught in the catch clause....
For the entire code, see http://elgervanboxtel.nl/site/blog/xmlhttprequest-extended-with-promises
Here is my example code:
Request.get( window.location.href ) // make a request to the current page
.then(function (e) {
return e.response.length;
})
.then(function (responseLength) {
// log response length
console.info(responseLength);
// throw an error
throw new Error("throw error");
})
.catch(function(e) { // e.target will have the original XHR object
console.log(e.type, "readystate:", e.target.readyState, e);
});
The problem is, that the error gets thrown before your then block gets called.
Solution
Request
.get('http://google.com')
.catch(function(error) {
console.error('XHR ERROR:', error);
})
.then(function(responseLength) {
// log response length
console.info(responseLength);
// throw an error
throw new Error("throw error");
})
.catch(function(error) {
// e.target will have the original XHR object
console.error('SOME OTHER ERROR', error);
});
Hint
Why are you not using fetch()?