Rectangle 27 15

The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.

jQuery and AJAX response header - Stack Overflow

jquery ajax redirect header http-status-code-302
Rectangle 27 15

The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.

jQuery and AJAX response header - Stack Overflow

jquery ajax redirect header http-status-code-302
Rectangle 27 15

The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.

jQuery and AJAX response header - Stack Overflow

jquery ajax redirect header http-status-code-302
Rectangle 27 15

The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.

jQuery and AJAX response header - Stack Overflow

jquery ajax redirect header http-status-code-302
Rectangle 27 15

The unfortunate truth about AJAX and the 302 redirect is that you can't get the headers from the return because the browser never gives them to the XHR. When a browser sees a 302 it automatically applies the redirect. In this case, you would see the header in firebug because the browser got it, but you would not see it in ajax, because the browser did not pass it. This is why the success and the error handlers never get called. Only the complete handler is called.

The 302 response from the Web server should always include an alternative URL to which redirection should occur. If it does, a Web browser will immediately retry the alternative URL. So you never actually see a 302 error in a Web browser

Here are some stackoverflow posts on the subject. Some of the posts describe hacks to get around this issue.

jQuery and AJAX response header - Stack Overflow

jquery ajax redirect header http-status-code-302
Rectangle 27 16

jqXHR
getResponseHeader()
always()
XMLHttpRequest
this.getResponseHeader('Location')

Bear in mind that if your server also sends a redirect status code (301/ 302) that redirect will be automatically followed, and there's no way to access the intermediate-headers returned.

How to get read data from response header in jquery/javascript - Stack...

javascript jquery httpresponse response-headers
Rectangle 27 16

jqXHR
getResponseHeader()
always()
XMLHttpRequest
this.getResponseHeader('Location')

Bear in mind that if your server also sends a redirect status code (301/ 302) that redirect will be automatically followed, and there's no way to access the intermediate-headers returned.

How to get read data from response header in jquery/javascript - Stack...

javascript jquery httpresponse response-headers
Rectangle 27 57

Without handling cache headers manually, it is not possible. Normally, 304 responses are not made available through the XHR API:

the user agent must act as if the server gave a 200 OK response with the appropriate content

jQuery normally doesn't know there was a 304 response, because the browser tells polite lies to JavaScript about what is actually happening over the network.

But there is good news (kind of): you can get Ajax to produce a 304 response, but only by manually setting the HTTP cache headers If-Modified-Since or If-None-Match in the request:

The user agent must allow setRequestHeader() to override automatic cache validation by setting request headers (e.g., If-None-Match, If-Modified-Since), in which case 304 Not Modified responses must be passed through.

So, you can use code like:

One fundamental difficulty is how do you know what last-modified date or ETag to send? The browser has cache information that it uses for sending requests, but it won't share that information with JavaScript. Fortunately, jQuery keeps track of the Last-Modified and ETag headers from Ajax responses, so you can use ifModified:true to have jQuery set those header values the next time it sends a request for that resource.

304 responses do not carry data. This is by design. The assumption is that if you have elected to use caching, you should have a copy of the data already in your cache! If getting no data from the sever is a problem (i.e., because you don't already have that data) why are you using caching? Caching should be used when you have the old data on hand and only want new data; thus, getting back no data with a 304 should not be a problem.

jQuery must have a last-modified date or an ETag (to use with If-None-Match) stored from a previous request. The process goes like this:

The bottom line here is that you can use cache headers to get a JavaScript 304 response, but you can't access the browser's own ETag or last-modified date for a particular resource. So, the browser itself might know caching information about a resource, but your JavaScript code does not. In that case, the browser will use its cache headers to potentially get a real 304 response, but forward a 200 response to your JavaScript code, because JavaScript didn't send any cache information.

It is not possible to make JavaScript 304 requests align perfectly with actual network 304 responses, because the cache information known by your browser and the cache information known by your JavaScript code may differ in unpredictable ways. However, getting 304 requests correctly most of the time is good enough for most practical development needs.

Here's a brief server example written in Node.js (but it should be simple enough to port to other langauges):

require("http").createServer(function (req, res) {
  console.log(req.headers["if-modified-since"]);

  // always send Last-Modifed header
  var lastModDate = "Fri, 13 Feb 2013 13:43:19 GMT";
  res.setHeader("Last-Modified", lastModDate);

  // if the request has a If-Modified-Since header,
  //   and it's newer than the last modification,
  //   then send a 304 response; otherwise send 200
  if(req.headers["if-modified-since"] &&
     Date.parse(lastModDate) <= Date.parse(req.headers["if-modified-since"])) {
    console.log("304 -- browser has it cached");
    res.writeHead(304, {'Content-Type': 'text/plain'});
    res.end();
  } else {
    console.log("200 -- browser needs it fresh");
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('some content');
  }

}).listen(8080);

When running this server, you can load the page in your browser and perform two different tests in your browser console:

This script will always see a 200 response, even if the browser supplies a If-Modified-Since request header and gets a 304 (which will happen all requests after the first, after the browser sees the server's Last-Modifed response header).

The script supplies its own If-Modified-Since request header (two days after the server's last-modified date); it does not rely on whatever the browser supplies for If-Modified-Since, and therefore is allowed (per the XHR spec) to see 304 responses.

200
var xhr = new XMLHttpRequest();
xhr.open("GET", "/");
xhr.setRequestHeader("If-Modified-Since", "Fri, 12 Feb 2013 13:43:19 GMT");
xhr.send();
xhr.onload = function() { console.log(xhr.status); }

This is because the script uses a If-Modified-Since that is prior to the server's last-modified date, so the server always sends a 200. The server won't send a 304 because it assumes the client doesn't have a cached copy of the most recent version (i.e., the client announces that it's seen changes since Feb 12, but there was a change on Feb 13 that the client apparently hasn't seen).

"The user agent must allow setRequestHeader() to override automatic cache validation by setting request headers (e.g., If-None-Match, If-Modified-Since), in which case 304 Not Modified responses must be passed through. [RFC2616]"

I checked your If-Modified-Since+Last-Modified method with native XMLHttpRequest 2 and unfortunately Chrome always returns 200 and Firefox 301 cached result. Looks like there are no valid XMLHttpRequest cache validation possible at all.

@Binyamin I have reproduced the behavior described in my answer and added a complete server and client example. Are you sure your server was correctly configured to send 304 responses in response to recent If-Modified-Since values? The script can only observe 304 responses when the server actually sends 304 responses. Using an explicit If-Modified-Since allows existing 304 response to be visible to the script (rather than hidden as 200); it does not generate a 304 status where one doesn't already exist in the actual response.

How to check if jQuery.ajax() request header Status is "304 Not Modifi...

ajax jquery header http-status-code-304
Rectangle 27 1

use the jquery XHR object which as a method getAllResponseHeaders() which should provide what you are after.

Right, but since it's a 403 Forbidden access, I it's not firing because it doesn't succeed. That's why I use the 'complete' where the first object is the jqXHR object.

You can also get it by doing var jqXHR = $.ajax(); ajax returns it and the same is available.

I tried your recommendation link but the var jqXHR = $.ajax() returns null while the jqXHR from the erro callback is an empty string.

try using error(jqXHR, textStatus, errorThrown), same usage as success but is triggered on errors, like a 403

Yeah, you can see from the pastebin link, I've tried all callbacks that expose the xhr object, complete, success, error, $.ajax as a var, and statusCodes.

javascript - intercept response header with jquery ajax request - Stac...

javascript jquery ajax header response
Rectangle 27 4

In JavaScript, using XMLHttpRequest you can do that using getAllResponseHeaders() method.

How to get read data from response header in jquery/javascript - Stack...

javascript jquery httpresponse response-headers
Rectangle 27 4

In JavaScript, using XMLHttpRequest you can do that using getAllResponseHeaders() method.

How to get read data from response header in jquery/javascript - Stack...

javascript jquery httpresponse response-headers
Rectangle 27 159

http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
http://run.jsbin.com

As the source (aka origin) page and the target URL are at different domains (run.jsbin.com and www.ecb.europa.eu), your code is actually attempting to make a Cross-domain (CORS) request, not an ordinary GET.

In a few words, the same-origin policy says that browsers should only allow ajax calls to services at the same domain of the HTML page.

A page at http://www.example.com/myPage.html can only directly request services that are at http://www.example.com, like http://www.example.com/api/myService. If the service is hosted at another domain (say http://www.ok.com/api/myService), the browser won't make the call directly (as you'd expect). Instead, it will try to make a CORS request.

  • Will include an Origin header in the original request (with the page's domain as value) and perform it as usual; and then
Access-Control-Allow-Origin
  • If the expected headers don't come, the browser simply gives up (like it did to you).
GET
POST
application/json
OPTIONS

Was it just a typo? Sometimes the JavaScript code has just a typo in the target domain. Have you checked? If the page is at www.example.com it will only make regular calls to www.example.com! Other URLs, such as api.example.com or even example.com or www.example.com:8080 are considered different domains by the browser! Yes, if the port is different, then it is a different domain!

Add the headers. The simplest way to enable CORS is by adding the necessary headers (as Access-Control-Allow-Origin) to the server's responses. (Each server/language has a way to do that - check some solutions here.)

Last resort: If you don't have server-side access to the service, you can also mirror it (through tools such as reverse proxies), and include all the necessary headers there.

Thanks, that is a lot of information. Now I can perform the necessary research to proceed.

Hi acdcjunior, how do I mirror the web service which I want to get access to?

@Franva You'll have to setup a HTTP server (e.g. Tomcat, Apache with PHP, IIS with ASP) and place a page there that, for every request, it opens a socket to the actual service (the service you are mirroring), requests the actual data and then gives it as response. Of course, you'll do that through code (Java, PHP, ASP, etc.).

@acdcjunior Please correct me if my understanding is right. If I enter some URL in browser directly, it will redirect to the new domain url automatically without Access-Control-Allow-Origin. For example, when using WIF, the user will be redirected to third party login page when login for the first time.

@machinarium I'm not sure if I understand what you meant, but I'll try to answer (tell me if I got anything wrong): If you enter the URL in the browser's address bar, the presence or absence of Access-Control-Allow-Origin in that URL's headers won't matter at all - the browser will open the URL as usual. The same-origin policy (and the requirement for the Access-Control-Allow-Origin header) only applies to Ajax calls.

javascript - jQuery xml error ' No 'Access-Control-Allow-Origin' heade...

javascript jquery ajax xml-parsing
Rectangle 27 159

http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
http://run.jsbin.com

As the source (aka origin) page and the target URL are at different domains (run.jsbin.com and www.ecb.europa.eu), your code is actually attempting to make a Cross-domain (CORS) request, not an ordinary GET.

As the source (origin) page and the target URL are at different domains, your code is actually attempting to make a Cross-domain (CORS) request, not an ordinary GET.

In a few words, the same-origin policy says that browsers should only allow ajax calls to services at the same domain of the HTML page.

Example: A page in http://www.example.com/myPage.html can only directly request services that are in http://www.example.com, like http://www.example.com/testservice/etc. If the service is in other domain, the browser won't make the direct call (as you'd expect). Instead, it will try to make a CORS request.

A page at http://www.example.com/myPage.html can only directly request services that are at http://www.example.com, like http://www.example.com/api/myService. If the service is hosted at another domain (say http://www.ok.com/api/myService), the browser won't make the call directly (as you'd expect). Instead, it will try to make a CORS request.

  • Will first send an OPTION request to the target URL
  • Will include an Origin header in the original request (with the page's domain as value) and perform it as usual; and then

only if

Access-Control-Allow-Origin
OPTION
  • If the expected headers don't come, the browser simply gives up (like it did to you).
GET
POST

How to solve it? The simplest way is to enable CORS (enable the necessary headers) on the server.

application/json

If you don't have server-side access to the service, you can also mirror it, and include de necessary headers there.

OPTIONS

Was it just a typo? Sometimes the JavaScript code has just a typo in the target domain. Have you checked? If the page is at www.example.com it will only make regular calls to www.example.com! Other URLs, such as api.example.com or even example.com or www.example.com:8080 are considered different domains by the browser! Yes, if the port is different, then it is a different domain!

Add the headers. The simplest way to enable CORS is by adding the necessary headers (as Access-Control-Allow-Origin) to the server's responses. (Each server/language has a way to do that - check some solutions here.)

Last resort: If you don't have server-side access to the service, you can also mirror it (through tools such as reverse proxies), and include all the necessary headers there.

Thanks, that is a lot of information. Now I can perform the necessary research to proceed.

Hi acdcjunior, how do I mirror the web service which I want to get access to?

@Franva You'll have to setup a HTTP server (e.g. Tomcat, Apache with PHP, IIS with ASP) and place a page there that, for every request, it opens a socket to the actual service (the service you are mirroring), requests the actual data and then gives it as response. Of course, you'll do that through code (Java, PHP, ASP, etc.).

@acdcjunior Please correct me if my understanding is right. If I enter some URL in browser directly, it will redirect to the new domain url automatically without Access-Control-Allow-Origin. For example, when using WIF, the user will be redirected to third party login page when login for the first time.

@machinarium I'm not sure if I understand what you meant, but I'll try to answer (tell me if I got anything wrong): If you enter the URL in the browser's address bar, the presence or absence of Access-Control-Allow-Origin in that URL's headers won't matter at all - the browser will open the URL as usual. The same-origin policy (and the requirement for the Access-Control-Allow-Origin header) only applies to Ajax calls.

javascript - jQuery xml error ' No 'Access-Control-Allow-Origin' heade...

javascript jquery ajax xml-parsing
Rectangle 27 159

http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
http://run.jsbin.com

As the source (aka origin) page and the target URL are at different domains (run.jsbin.com and www.ecb.europa.eu), your code is actually attempting to make a Cross-domain (CORS) request, not an ordinary GET.

In a few words, the same-origin policy says that browsers should only allow ajax calls to services at the same domain of the HTML page.

A page at http://www.example.com/myPage.html can only directly request services that are at http://www.example.com, like http://www.example.com/api/myService. If the service is hosted at another domain (say http://www.ok.com/api/myService), the browser won't make the call directly (as you'd expect). Instead, it will try to make a CORS request.

  • Will include an Origin header in the original request (with the page's domain as value) and perform it as usual; and then
Access-Control-Allow-Origin
  • If the expected headers don't come, the browser simply gives up (like it did to you).
GET
POST
application/json
OPTIONS

Was it just a typo? Sometimes the JavaScript code has just a typo in the target domain. Have you checked? If the page is at www.example.com it will only make regular calls to www.example.com! Other URLs, such as api.example.com or even example.com or www.example.com:8080 are considered different domains by the browser! Yes, if the port is different, then it is a different domain!

Add the headers. The simplest way to enable CORS is by adding the necessary headers (as Access-Control-Allow-Origin) to the server's responses. (Each server/language has a way to do that - check some solutions here.)

Last resort: If you don't have server-side access to the service, you can also mirror it (through tools such as reverse proxies), and include all the necessary headers there.

Thanks, that is a lot of information. Now I can perform the necessary research to proceed.

Hi acdcjunior, how do I mirror the web service which I want to get access to?

@Franva You'll have to setup a HTTP server (e.g. Tomcat, Apache with PHP, IIS with ASP) and place a page there that, for every request, it opens a socket to the actual service (the service you are mirroring), requests the actual data and then gives it as response. Of course, you'll do that through code (Java, PHP, ASP, etc.).

@acdcjunior Please correct me if my understanding is right. If I enter some URL in browser directly, it will redirect to the new domain url automatically without Access-Control-Allow-Origin. For example, when using WIF, the user will be redirected to third party login page when login for the first time.

@machinarium I'm not sure if I understand what you meant, but I'll try to answer (tell me if I got anything wrong): If you enter the URL in the browser's address bar, the presence or absence of Access-Control-Allow-Origin in that URL's headers won't matter at all - the browser will open the URL as usual. The same-origin policy (and the requirement for the Access-Control-Allow-Origin header) only applies to Ajax calls.

javascript - jQuery xml error ' No 'Access-Control-Allow-Origin' heade...

javascript jquery ajax xml-parsing
Rectangle 27 7

Lee's answer already adequately addresses the case of HTML responses - scripts embedded in these are not in fact executed automatically unless you add the HTML to the DOM, contrary to the erroneous documentation you quoted.

That leaves the other case asked about in your question title - preventing script responses from being executed automatically when received. You can do this easily using the dataType setting.

$.ajax('myscript.js', {
    dataType: 'text',
    success: function (response) {
        // Do something with the response
    }
})

Setting dataType to 'text' will cause jQuery to disregard the Content-Type header returned from the server and treat the response like plain text, thus preventing the default behaviour for JavaScript responses (which is to execute them). From the (recently corrected) docs:

The type of pre-processing depends by default upon the Content-Type of the response, but can be set explicitly using the dataType option. If the dataType option is provided, the Content-Type header of the response will be disregarded.

If text or html is specified, no pre-processing occurs. The data is simply passed on to the success handler, and made available through the responseText property of the jqXHR object.

prevent jquery ajax to execute javascript from script or html response...

javascript html ajax jquery
Rectangle 27 24

Simple version (does not send images)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>
  • You can run this before the document is ready
  • You can remove and re-add the form and it will still work
  • It will post to the same location as the normal form, specified in the form's "action" attribute
jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

I wanted to edit Alfrekjv's answer but deviated too much from it so decided to post this as a separate answer.

Does not send files, does not support buttons, for example clicking a button (including a submit button) sends its value as form data, but because this is an ajax request the button click will not be sent.

To support buttons you can capture the actual button click instead of the submit.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});
HTTP_X_REQUESTED_WITH

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}

How would this work if you DID want to send a file with this form?

@YamiMedina that's not a simple solution, you need to send the entire request in a different format (multipart format) with the file data

javascript - jQuery AJAX submit form - Stack Overflow

javascript jquery ajax submit html-form
Rectangle 27 24

Simple version (does not send images)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>
  • You can run this before the document is ready
  • You can remove and re-add the form and it will still work
  • It will post to the same location as the normal form, specified in the form's "action" attribute
jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

I wanted to edit Alfrekjv's answer but deviated too much from it so decided to post this as a separate answer.

Does not send files, does not support buttons, for example clicking a button (including a submit button) sends its value as form data, but because this is an ajax request the button click will not be sent.

To support buttons you can capture the actual button click instead of the submit.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});
HTTP_X_REQUESTED_WITH

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}

How would this work if you DID want to send a file with this form?

@YamiMedina that's not a simple solution, you need to send the entire request in a different format (multipart format) with the file data

javascript - jQuery AJAX submit form - Stack Overflow

javascript jquery ajax submit html-form
Rectangle 27 24

Simple version (does not send images)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>
  • You can run this before the document is ready
  • You can remove and re-add the form and it will still work
  • It will post to the same location as the normal form, specified in the form's "action" attribute
jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

I wanted to edit Alfrekjv's answer but deviated too much from it so decided to post this as a separate answer.

Does not send files, does not support buttons, for example clicking a button (including a submit button) sends its value as form data, but because this is an ajax request the button click will not be sent.

To support buttons you can capture the actual button click instead of the submit.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});
HTTP_X_REQUESTED_WITH

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}

How would this work if you DID want to send a file with this form?

@YamiMedina that's not a simple solution, you need to send the entire request in a different format (multipart format) with the file data

javascript - jQuery AJAX submit form - Stack Overflow

javascript jquery ajax submit html-form
Rectangle 27 24

Simple version (does not send images)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>
  • You can run this before the document is ready
  • You can remove and re-add the form and it will still work
  • It will post to the same location as the normal form, specified in the form's "action" attribute
jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

I wanted to edit Alfrekjv's answer but deviated too much from it so decided to post this as a separate answer.

Does not send files, does not support buttons, for example clicking a button (including a submit button) sends its value as form data, but because this is an ajax request the button click will not be sent.

To support buttons you can capture the actual button click instead of the submit.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});
HTTP_X_REQUESTED_WITH

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}

How would this work if you DID want to send a file with this form?

@YamiMedina that's not a simple solution, you need to send the entire request in a different format (multipart format) with the file data

javascript - jQuery AJAX submit form - Stack Overflow

javascript jquery ajax submit html-form
Rectangle 27 24

Simple version (does not send images)

<form action="/my/ajax/url" class="my-form">
...
</form>
<script>
    (function($){
        $("body").on("submit", ".my-form", function(e){
            e.preventDefault();
            var form = $(e.target);
            $.post( form.attr("action"), form.serialize(), function(res){
                console.log(res);
            });
        });
    )(jQuery);
</script>
  • You can run this before the document is ready
  • You can remove and re-add the form and it will still work
  • It will post to the same location as the normal form, specified in the form's "action" attribute
jQuery(document).submit(function(e){
    var form = jQuery(e.target);
    if(form.is("#form-id")){ // check if this is the form that you want (delete this check to apply this to all forms)
        e.preventDefault();
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: form.serialize(), // serializes the form's elements.
            success: function(data) {
                console.log(data); // show response from the php script. (use the developer toolbar console, firefox firebug or chrome inspector console)
            }
        });
    }
});

I wanted to edit Alfrekjv's answer but deviated too much from it so decided to post this as a separate answer.

Does not send files, does not support buttons, for example clicking a button (including a submit button) sends its value as form data, but because this is an ajax request the button click will not be sent.

To support buttons you can capture the actual button click instead of the submit.

jQuery(document).click(function(e){
    var self = jQuery(e.target);
    if(self.is("#form-id input[type=submit], #form-id input[type=button], #form-id button")){
        e.preventDefault();
        var form = self.closest('form'), formdata = form.serialize();
        //add the clicked button to the form data
        if(self.attr('name')){
            formdata += (formdata!=='')? '&':'';
            formdata += self.attr('name') + '=' + ((self.is('button'))? self.html(): self.val());
        }
        jQuery.ajax({
            type: "POST",
            url: form.attr("action"), 
            data: formdata, 
            success: function(data) {
                console.log(data);
            }
        });
    }
});
HTTP_X_REQUESTED_WITH

PHP

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    //is ajax
}

How would this work if you DID want to send a file with this form?

@YamiMedina that's not a simple solution, you need to send the entire request in a different format (multipart format) with the file data

javascript - jQuery AJAX submit form - Stack Overflow

javascript jquery ajax submit html-form