tcp handshake terminated by FIN /JSON data not retrieved - javascript

Hi
I have a website html embadded with java script, the website uploaded into apache tomcat, the website suppose to contact another server and retrieve json data back, this is not happening the packet tracing shows the tcp handshake is terminated by a FIN state the packet send before the FIN state has a checksum incorrect, I'm not sure how to troubleshoot this ? do you think the checksum incorrect is terminating the handshake ? and hwo to avoide that ? the following is my ajax jquery code
note: both apache server and the other server are in the same domain.
Thank in advance
LS
$(document).ready( function() {
var home_add='http://myhome.net:3300/gateway';
$('#handshake').click(function(){
alert(" sending json data");
$.ajax({ /* start ajax function to send data */
url:home_add,
type:'POST',
datatype:'json',
contanttype:'text/json',
async: false,
error:function(){ alert("handshake didn't go through")}, /* call disconnect function */
data:{
"supportedConnectionTypes": "long-polling",
"channel": "/meta/handshake",
"version": "1:0"
},
success:function(data){
$("p").append(data+"<br/>");
alert("sucessful handshake")
}
})
})
})

You seem to be misunderstanding the same-origin policy. The same-origin policy used by XMLHttpRequest, the basis for jQuery's AJAX functionality, is:
The two hostnames must be exactly the same (not just part of a higher level domain).Example: A web page from careers.stackoverflow.com can access the same domain but not beta.careers.stackoverflow.com, stackoverflow.com, or foo.stackoverflow.com.
The two protocols must be exactly the same (http/https).Example: A web page from http://stackoverflow.com cannot access https://stackoverflow.com and vice-versa.
The two port numbers must be exactly the same (except in Internet Explorer).Example: A web page from http://stackoverflow.com cannot access http://stackoverflow.com:8080 and vice-versa in Firefox, Chrome, Safari, or Opera.
You will have to do one of these:
Use the Access-Control-Allow-Origin HTTP header in AJAX responses, with the obvious disadvantage of excluding browsers such as IE and older versions of the others that do not support it
Use JSONP, which is supported by jQuery though not for synchronous requests (which you should avoid anyway because they can hang the browser)
Proxy HTTP requests from the server your web page is served on to the other server

Related

local AJAX-call to remote site works in Safari but not in other browsers

I am maintaining a website that uses Javascript. The script uses jQuery and loads some content from the server at which the site is normally hosted.
Just for convenience while maintaining the site, I run a local copy of the site on my iMac. This works perfectly fine when I use Safari. But Firefox, Opera and Chrome refuse to work. I guess it is because of cross-domain-policy. (I couldn't test this with IE, because IE has to run in a virtual machine on my iMac, so for this reason it is not possible to access any local files)
Is there a setting within Firefox and the other browsers where I can tell the browser that it is ok to ajax-load files that are located on a remote server from a local html-page with a local javascript?
In a nutshell: This my html-page:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>some title</title>
<link rel="stylesheet" type="text/css" href="../css/stylesheet.css">
<script src="../js/jquery-2.1.3.min.js"></script>
<script src="../js/myScript.js"></script>
</head>
<body>
<!-- some content with a div-container to receive the ajax-content -->
</body>
</html>
This is myScript.js:
var errorMsg = function (msg) {
//insert the message into the html-page
};
var JSONerror = function (jqXHR, textStatus, errorThrown ) {
var msg = 'JSON-answer: '+jqXHR.responseText;
msg += '<br>'+'JSON-Errorstatus: '+textStatus;
if ($.type(errorThrown) === 'string') {
msg += '<br>'+'Error: '+errorThrown;
}
errorMsg(msg);
};
var JSONreceive = function (JSONobj, StatusString, jqXHR) {
//insert the data in JSONobj into the html-page
}
var StartAJAX = function () {
$.ajax({
url: 'http://my.domain.tld/cgi-bin/myPerlScript.pl',
data: "lastID=" + lastID
+ '&qkz=' + Math.random(),
dataType: "json",
success: JSONreceive,
error: JSONerror
});
};
There is also an event-listener, that listens for page-scroll and resize and checks some other constraints (like: is there already an ajax-call in progress?). This listener calls StartAJAX.
When it calls StartAJAX on a local copy of my page (file:///User/...) within Safari, I get the Ajax-content perfectly fine inserted into my html-document. within the other browsers i get the error-message inserted into the html-page. It is:
JSON-Answer: undefined
JSON-Errorstatus: error
Error:
Why does it work in Safari but not in Firefox, Chrome and Opera?
How can I make those browsers work?
(I need to test it with all browsers, because all browsers render the same html-domument differently, but I don't want to upload all files to the server after every change just to test it.)
EDIT:
After reading some answers, I want to make something clear, that I obviously did not make clear enough:
I am searching for settings in Webbrowsers
I will NOT change the settings of my remote webserver (Apache)
I will NOT manipulate any files on my remote machine (.htaccess)
I will NOT set up a webserver on my local iMac
I will NOT change the code of the AJAX-calls in my Javascript-files
I will NOT change the code of the Perl-Scripts on my remote Server
I can tell you why:
I am just doing a short maintainance, and i am too lazy to upload every manipulated file to the remote machine after I edited it. The settings of the webserver are fine for actual operation. I don't want to change them (and maybe forget the changes before finishing my work). Same for the scripts: Those parts that some of you want to change work fine as they are now. There is no reason to touch the Ajax-Calls, because there is nothing wrong with them in the productive environment.
All I want is that those stupid browsers Firefox, Opera and Chrome behave like Safari and process the Ajax-calls correctly.
BTW:
Please can anyone explain what is so risky to call data via Ajax from an other domain in Firefox, Opera or Chrome while it seems to be harmless doing the same thing in Safari?
CHROME
There is a plugin for chrome that will force it to ignore the security policy. You can also do this with flags. Note, please do not browse the "real web" with this enabled as it is a security risk for your computer.
FIREFOX
This thread indicates that there is presently no way to do this in firefox.
OPERA
Again, there does not appear to be a built in way to ignore CORS policies.
The alternative would be to have the server (http://my.domain.tld) in your case return the proper headers - specifically Access-Control-Allow-Origin:
To avoid this issues, you should develop your page (in your local computer it's ok) using a webserver (like apache, nginx, ...), so, your url ajax calls starts with the protocol http or https, not "file". "File" is the path of your file but using SO path system, not a web server system.
In the other hand, browsers has "Same Origin Policy". This is a security feature but what are the "problems" in web development using ajax calls? Well, your ajax calls always be done to the same server, for example, if you have your web on domain "http://my-domain.com" then your ajax calls must be to the same domain "http://my-domain.com".
To "bypass" SOP in ajax calls, you have three solutions:
Create a proxy on your "my-domain.com" that use curl (in php for example) to retrieve the data and return it to your ajax call
Use JSON-P
Allow your domain in your webserver (.htaccess for example) setting a proper configuration to CORS: http://enable-cors.org/
BTW
I am going to answer: "Please can anyone explain what is so risky to call data via Ajax from an other domain".
(Copy & paste from mozilla MDN https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy)
The same-origin policy restricts how a document or script loaded from
one origin can interact with a resource from another origin.
Same-origin Policy is used as a means to prevent some of the
Cross-site Request Forgery attacks.
Due to the same origin policy you aren't normally able to request resources from a different domain. Try adding crossDomain: true to your AJAX request since you are trying to make a request to a different domain.
$.ajax({
url: 'http://my.domain.tld/cgi-bin/myPerlScript.pl',
crossDomain: true,
data: "lastID=" + lastID
+ '&qkz=' + Math.random(),
dataType: "json",
success: JSONreceive,
error: JSONerror
});
Assuming the web site is domain A, and the perl script is on Domain B, you have two options:
1) Enable CORS on the web server at Domain B. http://enable-cors.org/
2) Create a script (php, perl, ashx, etc) on Domain A that calls the script on Domain B. The script on Domain A will act as a proxy and will be allowed by all web browsers.

Not cross-domain. XMLHttpRequest cannot load localhost:portNo1 . Origin localhost:portNo2 is not allowed by Access-Control-Allow-Origin

I have a server created from BaseHTTPServer.HTTPServer in Python at localhost:portNo1
Client-side is at localhost:portNo2 and at client-side, I am making a jQuery $.ajax POST request like this:
var request = $.ajax({
url: "http://localhost:portNo1",
type: "post",
dataType: 'json',
data: json_data
});
At server side, server gets the data from client and replies with its data.
def do_POST(self):
# Get client data
length = int(self.headers.getheader('content-length'))
data_string = self.rfile.read(length)
print data_string;
# Create response object
jsonObjStr = json.dumps(jsonObj);
self.send_response(200)
self.end_headers()
self.wfile.write(jsonObjStr);
What happens is that server is getting the data I sent, but there is no reply to the client and the callback at the fail event of $.ajax object executes at the client-side(error msg). I debugged and verified there is nothing with jsonObj. But I cannot see what is inside self.wfile object.
At the JS console, I get the following error also (it shows up at the JS console of Google Chrome and it doesn't show up in Firefox JS console):
XMLHttpRequest cannot load localhost:portNo1 . Origin localhost:portNo2 is not allowed by Access-Control-Allow-Origin. client.html:1
The JS console at Google Chrome points to html file, but that didn't make sense for me, either.
I checked the website and it seems that the error is generally caused due to cross-domain requests. However, I am communicating from one localhost port to another.
Well, that's the problem. Cross-origin restrictions do not allow you to communicate across ports without sending a Access-Control-Allow-Origin: * header.
A better solution would be to use Nginx or some other webserver to reverse proxy those two running applications to the same domain and port.

how Postman send requests? ajax, same origin policy

I have found this very useful Chrome extension called Postman. This is a very useful extension especially when you are into programming RESTful applications.
One thing I am confused on is that how this plugin/extension able to send POST request successfully on different domains?
I tried voting in a poll using Postman like this.
After submitting that, the vote was actually counted in, but when I tried doing that using AJAX and JavaScript, it fails, because of different origin policy of browsers.
How is that even possible?
Here is my code using jQuery. I used that in my computer though, localhost.
init: function() {
$.ajax({
url: 'http://example.com/vote.php',
type:'POST',
dataType: 'html',
data: {
id: '1'
},
success: function(data) {
if ( data == 'voted' ) {
$('.set-result').html( 'you already voted. try again after 24 hours' );
} else {
$('.set-result').html( 'successfully voted' );
}
}
});
},
Chrome packaged apps can have cross domain permissions. When you install Postman it promts you that this app will access any domain.
By placing */* in permissions section of your manifest file, you can do this.
Read more here:
https://developer.chrome.com/extensions/xhr.html
You can add the following header to sent Ajax request in postman.
Content-Type application/json
X-Requested-With XMLHttpRequest
Screenshot
Sounds like the site that hosts the poll (the "vote.php" script) needs to have an "Access-Control-Allow-Origin" header set to allow posting from a list of sites (or all sites).
A value of * for the header will allow posting from any website:
Access-Control-Allow-Origin: *
i.e. You could put the following at the top of vote.php
header('Access-Control-Allow-Origin: *');
Chrome extensions and apps are not subject to the same security limitations placed on normal webpages.
Additional debugging tips:
If you're trying to access remote services from web pages you have open on your local file system in your browser, you might find your browser applies different security rules to them than it does to files served from a web service.
e.g. If you open local files from a locational like C:\MyDocuments\weboot\index.htm (Windows) or \Users\joe\Sites\index.html (Mac) in your browser your AJAX request might not work, even with the header specified in most browsers.
Apple's Safari applies almost no cross domain restrictions to files opened locally but Firefox is much more strict about what it permits, with Chrome somewhere in the middle. Running a web server locally (e.g. on http://localhost/) is a good idea to avoid unexpected behaviour.
Additionally, other libraries that provide functions to handle Ajax requests (such as AngularJS) may require other headers to be set on the server by default. You can usually see the reason for failure in a browser debug console.
2021 Oct
In my investigation, I found out that you need an extra field in the header of your request. So simply add the following key-value into the header:
key: X-Requested-With | value: XMLHttpRequest

Sending POST message with AJAX Problem

I am currently trying to send a POST message which works fine except for the error that there are not correct credentials. However, after I add the credentials header, the message type is changed into OPTIONS and fails. I do not understand how adding a header causes the type to change to OPTIONS. Any help would be appreciated.
ajaxRequest = $j.ajax({
url: url,
type: 'POST',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth),
}
success: function(data, status) {
console.log("Success!!");
console.log(data);
console.log(status);
},
error: function(xhr, desc, err) {
console.log(xhr);
alert('fail')
console.log("Desc: " + desc + "\nErr:" + err);
}
});
EDIT: just to be more clear, I can literally go in and comment out the setRequestHeader function and it sends the message POST.
The problem you're encountering is because of cross-domain restrictions when using AJAX. When you try to set an authorization header, the browser issues what's known as a pre-flight request to see if the server will accept requests from this domain.
A pre-flight request is typically sent as an OPTIONS request. If the server you're invoking doesn't return an Access-Control-Allow-Origin header that matches your domain, the AJAX request is blocked.
There's more on this here: Cross-Origin Resource Sharing
"User agents can discover via a preflight request whether a cross-origin resource is prepared to accept requests, using a non-simple method, from a given origin."
I've run into the same problem- there are a few possible workarounds depending on your scenario.
If you have any way of setting the above mentioned header on the 3rd party server (some applications/services offer this) then that's probably the easiest way.
There's also a javascript library called EasyXDM that may work for you, but again, it will only be of use if you have access to the 3rd party server to upload a configuration file for this library.
Other options to investigate are PostMessage and Cross Domain Iframe communication. The latter is more of an old-school hack, the former is the recommended approach for newer browsers. It won't work for IE6/7.
The option we will probably end up using is a simple proxy- invoke our own server with the AJAX request, and on the server invoke the 3rd party server. This avoids the cross domain issue entirely, and has other advantages for our scenario.
I guess this is a problem in Internet Explorer. without explicitly telling the request-method (POST|GET) the request header doesn't contain the custom-header in IE, but it works in other browsers.
Yet try to post this in the bugs for jquery. Also try in other browsers.
Edit 1 : I saw this as a bug in jQuery 1.4.x .... I reported a bug report now.
The OPTIONS response happens when the server does not know how to respond to the ajax request.
I've seen it happen often when trying to post to a third-party domain (i.e. cross-site posting)
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
Have you tried:
Having some sort of callback on the url that is being posted to?
Explicitly setting the headers (I'm assuming you're using PHP) on the url that is being posted to?

How to POST data to an HTTP page from an HTTPS page

I know this is a long shot, but I figured I'd ask the question anyway.
I have an HTTPS page and am dynamically creating a form. I want to POST the form to an HTTP page. Is this possible without the browser popping up a warning? When I do this on IE8, I get the following message:
Do you want to view only the webpage content that was delivered securely?
Essentially, I'm asking about the inverse of question 1554237.
Sadly, I know of absolutely no way to not get warned when posting from HTTPS to HTTP. If you serve the form securely, the browser expects to submit the data securely as well. It would surprise the user if anything else was possible.
Nope, can't be done. Our good friend IE will always pop up that warning.
There is a way to do this if you write a back-end service of your own. So lets say you want to post an HTTP request to s1 using your front-end service fs1.
If you use Spring, you can use an ajax call from fs1 to a 'uri' that is recognized by your spring back-end, say bs1. Now, the service bs1 can make the call to the s1.
Pictorial representation here: http://i.stack.imgur.com/2lTxL.png
code:
$.ajax
({
type: "POST",
uri:/json/<methodName>
data: $('#Form').serialize(),
success: function(response)
{
//handle success here
},
error: function (errorResponse)
{
//handle failure here
}
})
You can solve this by either acting as a proxy for the form destination yourself (i.e. let the form submit to your server which in turn fires a normal HTTP request and returns the response), or to let access the page with the form by HTTP only.
If you don't need to actually redirect to the insecure page, you can provide a web service (authenticated) that fires off the request for you and returns the data.
For example:
From the authenticated page, you call doInsecure.action which you create as a web service over https. doInsecure.action then makes a manual POST request to the insecure page and outputs the response data.
You should be able to do this with the opensource project Forge, but it sounds like overkill. The Forge project provides a JavaScript interface (and XmlHttpRequest wrapper) that can do cross-domain requests. The underlying implementation uses Flash to enable cross-domain (including http <=> https) communication.
http://github.com/digitalbazaar/forge/blob/master/README
So you would load the Forge JavaScript and swf from your server over https and then do a Forge-based XmlHttpRequest over http to do the POST. This would save you from having to do any proxy work on the server, but again, it may be more work than just supporting the POST over https. Also, the assumption here is that there's nothing confidential in the form that is being posted.

Categories

Resources