I'm trying to make a chrome extension that requires to do some API calls to my secure server.
I'm testing this locally first, with my own created ssl certificates.
My problem is that when i try to do an API call to my server (https://:9000/api/project) i get an error saying: net::ERR_INSECURE_RESPONSE.
The weird thing is that i can perfectly do that POST call from other REST clients with no problem, so i know the issue is in the code of the chrome extension.
The xhr request is being done in the background.js script like this:
var sendProject = function(projectData) {
var openhuntURL = 'https://<mylocal>:9000/api/project';
xhr.open('POST', openhuntURL, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
callback(true);
}
else {
callback(false);
}
};
xhr.send(projectData);
};
I don't know what i should do to allow the extension to make that request.
By the way, just before that api call i make another api call to another website and it works just fine.
Thanks for your help!
I had the same issue, and comes to know that there is no such way you can override self signed certificate.
Related
I have a number of AJAX requests (made with regular JS) that seem to be causing trouble when they make requests of my Python GAE back end. Here's an example:
newGame: function() {
// Calls API to begin a new game, tells view to show placements
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState === XMLHttpRequest.DONE) {
// ... removed unnecessary code for this question
}
};
var requestOjb = {"user_name": battleshipCtrl.user};
xhttp.open('POST', requestPath + 'game', true);
xhttp.send(JSON.stringify(requestOjb));
},
I am getting a code 400 with a Parse Error, but only on my deployed server. Everything works fine on the dev server. The error says the problem is with my back-end function "new_game", but does not specify a line where the error occurred. The endpoint function works correctly when I access it directly from the API explorer, so I figure the problem must be a result of the data sent from my JS file. Here's that function anyway:
#endpoints.method(request_message=NEW_GAME_REQUEST,
response_message=GameForm,
path='game',
name='new_game',
http_method='POST')
def new_game(self, request):
"""Creates new game"""
user = User.query(User.name == request.user_name).get()
# ... removed unnecessary code for this question
return game.to_form('Good luck playing Battleship!')
The request message it's expecting takes the form of {'user_name': 'some_name'} and it appears, through console.log, that JS is sending it in the right format.
The log where the parse error comes up is interesting, because it shows a 200 code POST request, although it mentions the 400 error when I dive into that log.
I've double and triple checked that my code works on the dev server, and that I've got the exact same code deployed. I don't know where to look next to continue debugging this thing. Any help is appreciated.
Figured it out. I tried running the AJAX request with jQuery, and got a slightly different error message, which lead me to find that I had to set the request header, because it was causing the server to read the incoming data differently than it should have. The following AJAX request now works perfectly.
newGame: function() {
// Calls API to begin a new game, tells view to show placements
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState === XMLHttpRequest.DONE) {
// ... removed unnecessary code for this question
}
};
var requestOjb = {"user_name": battleshipCtrl.user};
xhttp.open('POST', requestPath + 'game', true);
xhttp.setRequestHeader('Content-type', 'application/json');
xhttp.send(JSON.stringify(requestOjb));
},
I have built a chrome extension and, at time of loading, I need to make a GET request to a server (trying it now from localhost).
Using Chrome debugger I can see that the call is made, but it is never received on the locahost server (which is running).
Javascript code:
$.get( "http://localhost:8080/myproject/api/getInfo", { userId: "me" } )
.done(function( data ) {
alert('Received!');
});
This is what I can see from Chrome debugger:
Request URL:http://localhost:8080/myproject/api/getInfo?userId=me
Request Headers
Provisional headers are shown
Accept:*/*
Origin:chrome-extension://ginkmpnhbepolafnopjackbgefh
Query String Parameters
view source
view URL encoded
userId:me
If I put http://localhost:8080/myproject/api/getInfo?userId=me directly on a browser it works well.
What is wrong?
I don't know what is problem in above code but same things I have done using below code via creating an AJAX XMLHttpRequest Object on chrome extension script.
var userid="me";
var xmlHttpRequest = (window.XMLHttpRequest) ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xmlHttpRequest.open("GET","http://localhost:8080/myproject/api/getInfo",true);
xmlHttpRequest.send("userid="+userid);
xmlHttpRequest.onreadystatechange = function()
{
if(xmlHttpRequest.readyState == XMLHttpRequest.DONE)
{
alert('Received!');
}
}
The problem I had was that the browser was blocking calls from the HTTPS site (where the plugin was displayed) to HTTP://localhost.
It started working when I deployed it to production with a HTTPS server URL.
In the process of working on a simple project (or at least I thought to be simple) Where a user clicks a button, and a random saying generated from php appears in the above textbox. I do not have access to the php file so I can't see the code and feel a bit lost. The problem I'm having I believe, is an error in the way Im handling the response from the server (the handleServerResponse function). Any advice would be appreciated.
In an attempt to debug, I've seen this message: (I've changed the url)
XMLHttpRequest cannot load http:somephp.php. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
the code thus far:
var xmlHttp = createXmlHttpRequestObject();
function createXmlHttpRequestObject(){
var xmlHttp;
if(window.ActiveXObject){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
xmlHttp = false;
}
}else{
try{
xmlHttp = new XMLHttpRequest();
}catch(e){
xmlHttp = false;
}
}
if(!xmlHttp)
alert("Error 1");
else
return xmlHttp;
}
$("#BtnReset").click(function () {
$("#TBSaying").val("");
})
$("#BtnGetSaying").click(function () {
process();
})
function process(){
if(xmlHttp.readyState==0 || xmlHttp.readyState==4){
xmlHttp.open("GET", "http://somephp.php", true);
xmlHttp.onreadystatechange = handleServerResponse;
xmlHttp.send(null);
}else{
setTimeout('process()', 1000);
}
}
function handleServerResponse(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
xmlResponse = xmlHttp.responseXML;
xmlDocumentElement = xmlResponse.documentElement;
message = xmlDocumentElement.firstChild.data
$("#TBSaying").val(message);
}else{
alert('error 2');
}
}
}
Read through the JQuery documentation and started fresh, uploaded it to the same server in which the php resides and it works. here is the final code: Thanks to all that advised!
$("#BtnReset").click(function () {
$("#TBSaying").val("");
})
$("#BtnGetSaying").click(function () {
process();
})
function process(){
// AJAX Code To Submit Form.
$.get("http://somephp.php",function(data){
$("#TBSaying").val(data);
});
}
Ajax calls from a browser are restricted by what is called "same origin restrictions". Basically this means that, by default, you can only make an Ajax call back to the same server that the web page came from. That means you cannot make a regular Ajax call to a server on another domain, port or protocol.
You can read about the same origin policy here.
There are a three ways around this restriction, but all require cooperation from a server.
CORS. The server you are making the request from puts headers in its responses that tell the browser whether a cross origin request is allowed or even what domains it is allowed from. This gives the browser permission to complete Ajax calls that are not from the same origin.
JSONP. You can read more about JSONP here. Basically, you request a script from the target server and the script is coded in such a way that it will provide you the answer you want (usually in the JSON data format).
Server proxy. You find or code a server proxy that will request the data from the other server for you. Because server to server communication is not limited by the same origin restrictions, you can sometimes find another server that allows cross-origin requests to it that will then get the data for you and then return it to you.
Your javascript seems horrible, but alas, wrong
"Access-Control-Allow-Origin" is a server-sided (php?) bug, sorry.
tell the server guys to add something like
header("Access-Control-Allow-Origin: *");
to see if your javascript is correct ^^
on a sidenote,
alert("Error 1"); should probably use console.log or throw new Error() instead..
why have xmlHttp as a global, can just use process(e){ var xhr=e.target;...} instead
don't do this setTimeout('process()', 1000); , do setTimeout(process, 1000);
I'm building a Chrome packaged app called Git Crx and as the name suggests it needs to go network requests to and from remote git repos using HTTPS (smart protocol) BUT if you attempt to do an XHR request to a url that returns 401, the XHR will fail without using the normal browser credentials machinery whereas previously packaged apps would show the browsers normal credentials request UI.
Now I think that does makes sense to me now, as Chrome Apps are supposed to be stand alone apps and not just webpages, they just happen to use the Chrome as a runtime.
But then the question is how do Chrome Apps now deal with authentication for sites that use normal http authentication (return 401 status code) instead of using OAuth which is supported by the authentication APIs available to Chrome apps?
So in researching to write this question well, I found my answer myself...
First based on getting back a 401 as the status from the XHR response, I can set the Authorization header to do authentication, heres code in the form of a QUnit test case:
asyncTest("check can do Basic Auth XHR", function() {
expect(1);
var authCreds = "maks:s3cret";
var oReq = new XMLHttpRequest();
function reqListener () {
if (this.status == 200) {
equal(this.responseText.trim(), "the secret", "expect correct res text from server");
start();
} else if (this.status == 401) {
oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", "http://acme.test.com/auth-test", true);
oReq.setRequestHeader("Authorization", "Basic "+btoa(authCreds));
oReq.send();
}
}
oReq.onload = reqListener;
oReq.open("get", "http://acme.test.com/auth-test", true);
oReq.send();
});
But that is making an assumption that the scheme is Basic but it could be Digest or NTLM, so you also need to parse the response header as well...
var authType = oReq.getResponseHeader('WWW-Authenticate');
// do auth based on type...
Hope this helps others in the same boat in the future...
In my extension, I create Access Level as "All" as well as I add whitelists as http://*/* too for every domain.
And I have following code in my JS file (which run as end script):
var feedbackmsg = "message goes here";
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', 'http://mysitename.com/feedback.php', true);
xmlhttp.onreadystatechange = handleServerResponse;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send("html=" + feedbackmsg);
function handleServerResponse() {
if (xmlhttp.readyState == 4) {
alert(xmlhttp.getAllResponseHeaders());
if (xmlhttp.status == 200) {
alert("send");
} else {
alert("error");
}
}
}
Whenever I run it, I am getting no header respond in alert box as well as error alert message. How can I resolve the problem?
Whether or not it's an extension, XMLHttpRequest (if injected into a page) isn't allowed to access anything outside the page's current domain, I think. The console just says that the request was cancelled. At least, that was the case for me when I tested it just now. (I didn't have any urls in the whitelist or blacklist when I tested, but the Access option was set to "all".)
You can try going to the same domain as the one you want to "call" with the XHR object in your code, and see if it succeeds then. If it does, you'll know it's because the domain of the page and the XHR request must match.
However, it appears you can do cross-site ajax request from the extension's global page (oddly enough). At least it seemed to work for me just now. That's actually a little scary (I'd prefer it to be more difficult to call up a random server from an extension) but it worked.
Don't know if that helps you out, though.