1

I know how to use jQuery well, but I don't know so much pure JavaScript.

This is my jQuery code:

$(document).ready(function() {
    $.get('http://jsonip.com/', function(r){
        var ip_address = r.ip;
        my_function(ip_address);
    });
    function my_function(ip_address){
        var url = "Url_to my server hosted on a different domain";
        var data = {number:"1286", ip: ip_address};
        $.ajax({
            url: url, 
            type: "POST", 
            dataType: 'json', 
            crossDomain: true, 
            data: {data: data}, 
            success: function (data) {console.log(JSON.stringify(data));}, 
            error: function (xhr, error) {console.log("There was an error and data was not posted.");}});}
});

What it does: it is pasted in any website, then it picks any visitors ip address and send that as JSON to my server as variable data.

Problem: the code is working perfectly okay in some sites but not all the sites due to jQuery dependency. And I want to remove this and use pure JavaScript.

I am getting great answers but CORS is not working, there failing them. I am using different domains since the site we are sending data to is hosted on another server.

halfer
  • 19,824
  • 17
  • 99
  • 186
ben
  • 6,000
  • 5
  • 35
  • 42
  • 1
    If you're adding this code to a page, why don't you just check if jQuery is present and load it from a CDN, etc. if it isn't? – Sam Hanley Jan 13 '15 at 20:03
  • It should technically work in more sites because the jQuery dependency fixes many cross browser quirks – Christopher Marshall Jan 13 '15 at 20:04
  • 3
    You dont need the first ajax request, your server side should be able to get it from the request headers. You can check if jQuery is loaded with this line `if (window.jQuery)`, as someone already suggested, if it isn't loaded just use the code in this [answer](http://stackoverflow.com/questions/10113366/load-jquery-with-javascript-and-use-jquery) to load it in – Scriptable Jan 13 '15 at 20:04
  • ben, jQuery *is* JS, you know, so the problem is not the way jQ uses JS but in your code. – Roko C. Buljan Jan 13 '15 at 20:06
  • I have tried that, but it will be tired to do for hundreds of websites where the code will be used – ben Jan 13 '15 at 20:08

3 Answers3

2

As mentioned in my commment above, you do not need the first ajax request as you can get this information from the request headers (PHP Example below) from your AJAX request.

To make sure that your website(s) have jQuery loaded you can run a check in your script and load it in dynamically. Using some code from this answer. See below for an example:

// Anonymous "self-invoking" function
(function() {
    // Load the script
    var script = document.createElement("SCRIPT");
    script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
    script.type = 'text/javascript';
    document.getElementsByTagName("head")[0].appendChild(script);

    // Poll for jQuery to come into existance
    var checkReady = function(callback) {
        if (window.jQuery) {
            callback(jQuery);
        }
        else {
            window.setTimeout(function() { checkReady(callback); }, 100);
        }
    };

    // Start polling...
    checkReady(function($) {
        var url = "Url_to my server hosted on a different domain";
        var data = {number:"1286", ip: ip_address};
        $.ajax({
            url: url, 
            type: "POST", 
            dataType: 'json', 
            crossDomain: true, 
            data: {data: data}, 
            success: function (data) {console.log(JSON.stringify(data));}, 
            error: function (xhr, error) {console.log("There was an error and data was not posted.");
        });
    });
})();

To get the IP Address from your ajax request: (PHP) Source

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $ip = $_SERVER['REMOTE_ADDR'];
} 
Community
  • 1
  • 1
Scriptable
  • 19,402
  • 5
  • 56
  • 72
1

The annoying part is that you need to do a cross-domain POST to send your data. There's a W3C standard for this called Cross-Origin Resource Sharing (CORS). Check out this tutorial for more info.

You'll want to put this at the bottom of the page. Different browsers handle ready state change events differently, so let's just avoid them.

<script>
    // Once the JSONP script loads, it will call this function with its payload.
    function getip(ipJson) {
        var method = 'POST';
        var url = 'URL of your server';

        // The XMLHTTPRequest is the standard way to do AJAX. Try to use CORS.
        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);
        }

        // Create your request body. It has to be form encoded. I'm not sure
        // where you get `number` from, so I've hard-coded it.
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
        xhr.send('number=1286&ip=' + ipJson.ip);
    }
</script>

<!-- Get the IP using JSONP so we can skip implementing that. -->
<script type="application/javascript" src="http://www.telize.com/jsonip?callback=getip"></script>

This probably only works in modern browsers, but it should work in most modern browsers.

Chris Bouchard
  • 806
  • 7
  • 12
  • Hello chris, How to use Cors is my problem now. I am trying it but it seems not to work. getting this "XMLHttpRequest cannot load my server. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:3000'; is therefore not allowed access. The response had HTTP status code 500." – ben Jan 13 '15 at 21:53
  • @ben Doing the Cross domain ajax request with pure JS can be quite tricky, you may get some issues, Most websites will have jquery already and those that dont will have a cached version in their browser, they will of been on one site with jquery before. The code in my answer below ensures you always have jquery available, reduces number of requests and only loads jquery in if its needed so will ensure your code works on all sites. jQuery will handle the browser specific and CORS issues you'll face. I think it would be the best option – Scriptable Jan 14 '15 at 11:35
0

Replace $.ready(function...) with document.addEventListener('DOMContentLoaded', function..., false).

Replace $.ajax with XMLHttpRequest:

var xhr = new XMLHttpRequest();

//var data = {number:"1286", ip: ip_address};
var data = new FormData();
data.append("number", "1286");
data.append("ip", ip_address); // As stated by Scriptable in the question comments, your server should be able to get it from the request headers.

xhr.onload = function() { console.log(JSON.stringify(this.response)); };

xhr.onerror = function() { console.log("There was an error and data was not posted.") };

xhr.open("POST", "URL to your server");
xhr.send(data);
Álvaro Martínez
  • 1,047
  • 7
  • 10
  • this one is attempting to send, but then it gives an error XMLHttpRequest cannot load http://my server. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500. – ben Jan 13 '15 at 21:49
  • You have to add the `Access-Control-Allow-Origin: *` header on your server to allow cross-origin requests. Check http://enable-cors.org/server.html for more info. – Álvaro Martínez Jan 13 '15 at 22:11