http post request with cross-origin in javascript - javascript

i have a problem with a http post call in firefox. I know that when there are a cross origin, firefox first do a OPTIONS before the POST to know the access-control-allow headers.
With this code i dont have any problem:
Net.requestSpeech.prototype.post = function(url, data) {
if(this.xhr != null) {
this.xhr.open("POST", url);
this.xhr.onreadystatechange = Net.requestSpeech.eventFunction;
this.xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
this.xhr.send(data);
}
}
I test this code with a simple html that invokes this function.
Everything is ok and i have the response of the OPTIONS and POST, and i process the response. But, i'm trying to integrate this code with an existen application with uses jquery (i dont know if this is a problem), when the send(data) executes in this case, the browser (firefox) do the same, first do a OPTION request, but in this case dont receive the response of the server and puts this message in console:
[18:48:13.529] OPTIONS http://localhost:8111/ [undefined 31ms]
Undefined... the undefined is because dont receive the response, but the code is the same, i dont know why in this case the option dont receive the response, someone have an idea?
i debug my server app and the OPTIONS arrive ok to the server, but it seems like the browser dont wait to the response.
edit more later: ok i think that the problem is when i run with a simple html with a SCRIPT tag that invokes the method who do the request run ok, but in this app that dont receive the response, i have a form that do a onsubmit event, i think that the submit event returns very fast and the browser dont have time to get the OPTIONS request.
edit more later later: WTF, i resolve the problem make the POST request to sync:
this.xhr.open("POST", url, false);
The submit reponse very quickly and can't wait to the OPTION response of the browser, any idea to this?

Due to the same origin policy, you can't send cross origin post,
you can workaround it by include sites in iframes (if have access to the domain) original site contains iframe to the outer site, the inner direction is legal.

Related

How to avoid "fake" AJAX requests in Chrome extension

I am writing a small Chrome extension, and my question mostly about the algorithms. Suppose, my extension should send some AJAX requests to my server. Is there any way to be sure that this particular AJAX request was received exactly from my extension? I mean, make sure that this is not the user sent this request by falsifying it. I will be grateful for any ideas.
You need to check request origin on your server which must contain your extension ID.
When you send AJAX request from your extension the Origin parameter will be like this
chrome-extension://<extension_id>
Now on server you need to check this origin. Example in php
$extensionID = "YOUR_EXTENSION_ID";
$origin = $_SERVER['HTTP_ORIGIN'];
if (strpos($origin, $extensionID) === false) {
// exit from code
exit();
}
Here is complete anwser how to find origin from request.
Now your server will receive AJAX request only from your extension. If someone copy your code and run from another extension, your server will not handle that request.
Note that this will protect you from falsifying requests from other extensions. User still can open your extension background page and send AJAX request from console.

spurious ajax OPTIONS request being made along with a GET request

I am making a standard ajax request with the code below
let x = new XMLHttpRequest();
x.onload = function(event) { …};
x.open("GET", url, true);
x.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
x.send();
The problem is that, for some reason I can't fathom, two ajax requests are made. The first one is an OPTIONS request and the second one is the GET request that I actually wanted. Any idea why?
My server is a nodejs app which I am starting using nodemon which restarts the server if it senses index.js has changed (this is helpful in development when you don't want to stop and restart the server). With this OPTIONS business, nodemon thinks my index.js has changed and restarts nodejs.
Additionally, the OPTIONS request results in a successful request that returns http 200. But, nothing is returned to the web page that initiated that ajax request in the first place (this could be that immediately after the OPTIONS request, nodejs is restarted by nodemon. Then the GET request is repeated, also with 200, and the web page gets the result
The problem is that, for some reason I can't fathom, two ajax requests are made. The first one is an OPTIONS request and the second one is the GET request that I actually wanted. Any idea why?
Because you're making a cross-origin call (for instance, from http://localhost to http://localhost:someport), which is normally disallowed by the Same Origin Policy. So the browser sends a "pre-flight" OPTIONS request to see if the server wants to allow the call via Cross-Origin Resource Sharing.

Chrome extension - how to get response of POST request user invoked from a webpage?

I am trying to create a chrome extension that navigates to a webpage, lets the user click a button on the webpage that sends an asynchronous post request, and to read that response and use it in the extension.
Everything that I am finding from my research is telling me to create the request in the extension itself, which I do not want to do, because I need the web page to make the request itself.
Is there a way to listen to a post request on the page itself on my background script?
You can use chrome.webRequest and onBeforeRequest to fire when a request is about to occur chrome.webRequest.onBeforeRequest.addListener(function callback). Parameters contains the HTTP request data. You also need to supply an extraInfoSpec of requestBody to the listener.
Below is a sample code snippet how to use onBeforeRequest:
const WEB_REQUEST = chrome.webRequest;
WEB_REQUEST.onBeforeRequest.addListener(
function(details) {
if(details.method == "POST")
console.log(JSON.stringify(details));
},
);
For more information regarding POST request, try to read the Chrome Extensions developer guide: https://developer.chrome.com/extensions/getstarted

IE 10/11 won't call repeating GET requests

During an AJAX photo upload, the POST request is sent with the photo and returned successfully. However, the server still has some resizing tasks to complete before the image can be displayed. I set a timeout to loop until the image can be found by setting its source to what it will be once the server processes the image.
All other browsers(Chrome/Safari/Firefox) work great by repeating the GET request and eventually find it. IE 10/11 send one GET, returns a 404 and won't send anymore requests.
I've also tried AJAX requests as GETs for the image, same thing.
Ideas?
Are you sure your get request isn't being cached? Try appending a random parameter to the request each get. This will make the browser think you're pulling a different uri and not use the cached response.
E.x. some site.com/source?ignoreme=1526353377
If using jQuery you can set cache: false in your $.ajax call as well. It basically does exactly what explained above for you automatically.

How to prevent ajax requests to follow redirects using jQuery

I use the jQuery ajax functions to access a web service, but the server, instead of returning a response with a status code describing a problem, the request is redirected to a page with a 200 header, describing the problem. I can't make any changes to this, so I need to solve it on the client somehow.
Example:
A request goes to some URL which is not found, so I receive a 302 Redirect to another location. A new request is sent, and I receive a 200 OK, thus preventing the error callback to fire.
Is there some way I can prevent the ajax request to follow redirects and instead invoke a callback, preferably the error method. Alternatively, is it possible to detect if a redirect has happened in the client?
I find your question interesting, but the problem in whole seems me more a misunderstanding. At least I'll try to explain my understanding of the problem.
The silent (transparent) redirection is the part of XMLHttpRequest specification (see here especially the words "... transparently follow the redirect ..."). The standard mention only that the user agent (the web browser) can prevent or notify of certain kinds of automatic redirections, but it's not a part of XMLHttpRequest. It's the part of HTTP client configuration (OS configuration) or the web browser configuration. So jQuery.ajax can't have any option where you can prevent redirection.
You can see that HTTP redirection is the part of HTTP protocol and not a part of XMLHttpRequest. So it's on the another level of abstraction or the network stack. For example the data from the XMLHttpRequest can be retrieved from the HTTP proxy or from the local browser cache, and it's the part of HTTP protocol. Mostly the server which provide the data and not the client can influence on caching.
You can compare the requirement from your question with the requirement to prevent changing of IP address of the web server or the changing of the IP route during the communication. All the things can be interesting in some scenarios, but there are parts of another level of the communication stack and can't be managed by jQuery.ajax or XMLHttpRequest.
The XMLHttpRequest standard say that the client configuration can have options which prevent redirection. In case of "Microsoft world", which I better know, you can look at WinHttpSetOption function which can be used to set WINHTTP_OPTION_DISABLE_FEATURE option with the WINHTTP_DISABLE_REDIRECTS value. Another way are the usage of WINHTTP_OPTION_REDIRECT_POLICY option with the WINHTTP_OPTION_REDIRECT_POLICY_NEVER value. One more feature which one can use in Windows is the WinHttpSetStatusCallback function which can set callback function received some notifications like WINHTTP_CALLBACK_FLAG_REDIRECT.
So it's do possible to implement your requirements in general, but the solution will be probably not independent from the operation system or the web browser and be not on the level of jQuery.ajax or XMLHttpRequest.
I don't believe it is possible. The underlying library (XHR) makes the new request transparently. That being said, what I have done in these situations (usually a session-timeout type of deal that takes me to a login page) is send back a custom response header. I also have setup a global ajax handler that checks for the presence of that header, and responds appropriately when present (for example, redirecting the whole page to the login screen).
In case you're interested, here's the jQuery code I have to watch for that custom header:
/* redirects main window when AJAX request indicates that the session has expired on the backend. */
function checkSession(event, xhr, ajaxOptions)
{
if (xhr.readyState == 4)
{
if(xhr.getResponseHeader("Login-Screen") != null && xhr.getResponseHeader("Login-Screen").length)
{
window.location.href='sessionExpired.html'; //whatever
}
}
}
$(document).ajaxComplete(checkSession)
I found a feature to check if your call has been redirected. It's xhr.state(): if it's "rejected" then a redirection happened.
Example with success callback:
request.success(function(data, textStatus, xhr)
{
if(xhr.state() == "resolved")
{
//no redirection
}
if(xhr.state() == "rejected")
{
//redirection
}
});
Example with error callback:
request.error(function(xhr, textStatus)
{
if (xhr.state() == "rejected")
{
//redirection
location.href = "loginpage";
} else
{
//some other error happened
alert("error");
}
});
I can't possibly add to the insightful wisdom of the previous coders who've responded, but I will add a specific case that others may find useful to know about.
I came across this 302 silent redirect in the context of SharePoint. I have some simple Javascript client code that pings a SharePoint sub-site, and if it receives a 200 HTTP response, it relocates to that site, via window.location. If it receives anything else, it gives the user a notice that the site doesn't exist.
However, in the case where the site exists but the user does not have permission, SharePoint silently redirects to an AccessDenied.aspx page. SharePoint has already done the HTTP 401 authentication handshake at the server/farm level - the user has access to SharePoint. But the access to the sub-site is handled I suppose using database flags of some sort. The silent redirect bypasses my "else" clause, so I can't throw up my own error. In my case, this is not a show-stopper - it is consistent predictable behavior. But it was a little surprising, and I learned something about HTTP requests in the process!
I was interested in the same thing and could not find the state() method mentioned by Takman and did a little digging for myself. For the sake of people turning up here in search of an answer, here are my findings:
As stated multiple times, you cannot prevent redirects, but you can detect them. According to MDN you can use the responseURL of the XMLHttpRequestObject, which will contain the final URL the response came from, after all redirects. Only caveat is that it is not supported by Internet Explorer (Edge has it). Since the xhr/jqXHR passed into the success/done function of jquery is an extension of the actual XMLHttpRequest, it should be available there, too.
While it is not possible to disable location redirect following in XmlHttpRequests, it is when using fetch():
fetch('url', {redirect: manual});
I suppose you receive a 200 response because the second time there is no redirection, because the 404 page does not expire, it is saved in the cache. That is to say that the second time the browser gives you the page in the cache.
There is a property "cache" in the ajax jquery.
http://api.jquery.com/jQuery.ajax/
You should write it to "false"
I'm not sure if this will apply in your case, but you can write code to respond to specific status codes in AJAX function -
$.ajax({
url: '/admin/secret/data',
type: 'POST',
contentType: 'application/json; charset=utf-8',
statusCode: {
200: function (data) {
alert('302: Occurred');
// Bind the JSON data to the UI
},
401: function (data) {
alert('401: Occurred');
// Handle the 401 error here.
}
}
});
In the request headers in the case of ajax request you will have the following
X-Requested-With XMLHttpRequest
By this criteria on the server side you can filter requests.

Categories

Resources