0

I am trying to send an ajax send request, but it always goes into error.

$('form#contactForm button.submit').click(function () {

            var contactName = $('#contactForm #contactName').val();
            var contactEmail = $('#contactForm #contactEmail').val();
            var contactSubject = $('#contactForm #contactSubject').val();
            var contactMessage = $('#contactForm #contactMessage').val();

            var data = {
                'contactName': contactName,
                'contactEmail': contactEmail,
                'contactSubject': contactSubject,
                'contactMessage': contactMessage
            };

            $.ajax({
                type: "POST",
                url: "/",
                data: data,
                dataType: 'json',
                contentType: "application/json",
                success: function (msg) {
                    alert('success message: ' + msg);
                    if (msg == 'OK') {
                        $('#image-loader').fadeOut();
                        $('#message-warning').hide();
                        $('#contactForm').fadeOut();
                        $('#message-success').fadeIn();
                        $('#contactForm button.submit').prop('disabled', true);
                    }
                    else {
                        $('#image-loader').fadeOut();
                        $('#message-warning').html(msg);
                        $('#message-warning').fadeIn();
                    }

                },
                error: function (err) {
                    if (contactName.length === 0 || contactEmail.length === 0 || contactSubject.length === 0 ||
                        contactMessage.length === 0) {
                        $('#message-warning').html('Please check form once again.');
                        $('#message-warning').fadeIn();
                        event.preventDefault();
                    }
                    alert('inside error: ' + err.message);
                }
            });
            return false;
});

This always shows alert('inside error: ' + err.message);in error.I also tried data: JSON.stringify(data)and it didn't work either. Is there a problem with datavariable? Where is the problem?

Network tab:

Request URL:http://localhost:3000/
Request Method:POST
Status Code:400 Bad Request
Remote Address:[::1]:3000
Response Headers
view source
Connection:keep-alive
Content-Length:24
Content-Type:text/html; charset=utf-8
Date:Sun, 23 Oct 2016 00:12:43 GMT
ETag:W/"18-9LwX+BuZqYnTTqGm6GcNuA"
X-Powered-By:Express
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:102
Content-Type:application/json
Host:localhost:3000
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
X-Requested-With:XMLHttpRequest
Request Payload
contactName=My+Name&contactEmail=email%40email.com&contactSubject=My+Subject&contactMessage=My+Message

backend post

router.post('/', function (req, res) {
    if (typeof req.body.contactName === 'undefined' || typeof req.body.contactEmail === 'undefined' ||
        typeof req.body.contactSubject === 'undefined' || typeof req.body.contactMessage === 'undefined' ||
        !validator.isEmail(req.body.contactEmail)) {
        return res.status(400).send('error');
    }
    mail.sendMail(req.body.contactName, req.body.contactEmail, req.body.contactSubject, req.body.contactMessage);
    return res.status(200).send('okay');
});
Munchmallow
  • 311
  • 1
  • 2
  • 15
  • 1
    What is the error ? Check the response of the ajax call also – Shyju Oct 22 '16 at 23:53
  • 1
    Hard to say, request looks ok. Go to the developer tools in your browser and check in the Network tab if you pass the data along with your request. And check what the backend returns because if the error function triggers, that means the backend returns something other than 200. – Chris Dąbrowski Oct 22 '16 at 23:54
  • You put `url: "/"`, are you sure this is the page you want to call? – nicovank Oct 22 '16 at 23:56
  • @nicovank yes, my contact form is on my homepage. – Munchmallow Oct 23 '16 at 00:00
  • @KrzysztofDąbrowski I have just checked the status and it was 200. Message was also sent, but ajax still shows error alert. – Munchmallow Oct 23 '16 at 00:00
  • @Shyju err.message just says "Undefined" – Munchmallow Oct 23 '16 at 00:00
  • Try removing `dataType: 'json'` - the response doesn't look like JSON – sideroxylon Oct 23 '16 at 00:02
  • @Munchmallow because the first argument of the error function is the XHR object. What is the value of the second argument? – Chris Dąbrowski Oct 23 '16 at 00:05
  • Well your status code says it all: `Status Code:400 Bad Request`. – Terry Oct 23 '16 at 00:15
  • I added network tab. If I set data as JSON.stringtify(data), I get status 200, but still request shows `err.message`and it is `undefined`. If l set data as `data`, request shows 400. – Munchmallow Oct 23 '16 at 00:15
  • You shouldn't need to JSON stringily your data: your data is already a JS object, there is no need to convert any further. What code is handling the incoming POST request at the `/` url? – Terry Oct 23 '16 at 00:20
  • Added backend part. @Terry It gets request and sends it to `sendMail` function which contains 'nodemailer' for sending mail via Outlook. – Munchmallow Oct 23 '16 at 00:26
  • your URL where you are posting data does it have a method to consume post request? – Akshay Oct 23 '16 at 00:30
  • have you debug in your backend? you can insert a break point right before your request handler function. And see what is included in your variable `req.body`. – Enix Oct 23 '16 at 00:31
  • Note that the server's responses – `.send('error')` and `.send('okay')` – aren't valid JSON for `dataType: 'json'` to understand. The request/response may be succeeding, only to `error` when jQuery attempts to parse the response. (What is the value of the 3rd argument – `errorThrown` – to jQuery's `error` handler?) – Jonathan Lonowski Oct 23 '16 at 00:32
  • @Akshay I have a post router in backend if you asking that. – Munchmallow Oct 23 '16 at 00:34
  • @Enix Nothing is wrong with request. It works perfectly. Only ajax request has problem – Munchmallow Oct 23 '16 at 00:35
  • @JonathanLonowski I was first testing on Postman. Those `send()` were for postman. I removed them. 3rd value is "Bad Request" – Munchmallow Oct 23 '16 at 00:36
  • You mentioned in a previous comment "*but still request shows `err.message` and it is `undefined`*." The 1st argument to `error` with `jQuery.ajax()` isn't an `Error` instance; it's a [`jqXHR`](https://api.jquery.com/Types/#jqXHR). Try logging `err.responseText`. – Jonathan Lonowski Oct 23 '16 at 00:38
  • `err.responseText` shows my content of `error.ejs`. – Munchmallow Oct 23 '16 at 00:41

3 Answers3

1

I have removed dataType: 'json'and contentType: "application/json"and ajax request succeeded. I still don't know why but it worked after removing them.

Munchmallow
  • 311
  • 1
  • 2
  • 15
  • The response is not JSON. See other answer. Also [HERE](http://stackoverflow.com/questions/18701282/what-is-content-type-and-datatype-in-an-ajax-request) – sideroxylon Oct 23 '16 at 04:11
0

dataType refers to the expected response from the server - see HERE. If the response is not JSON, remove dataType: 'json' from the ajax function, and jQuery will make an intelligent guess.

sideroxylon
  • 4,338
  • 1
  • 22
  • 40
  • See: https://jsfiddle.net/ema79prk/1/ is working. Change `dataType: 'json'` to `dataType: 'xml'` and you'll get a `parseerror` – nicovank Oct 23 '16 at 00:11
0

The ajax client expects your response MIME type as 'json', however you provided a plain text 'okay' as response.

If you still need to send json as a response, you can make use of res.type change your backend like this:

router.post('/', function (req, res) {
    if (typeof req.body.contactName === 'undefined' || typeof req.body.contactEmail === 'undefined' ||
        typeof req.body.contactSubject === 'undefined' || typeof req.body.contactMessage === 'undefined' ||
        !validator.isEmail(req.body.contactEmail)) {
        return res.status(400).type('json').send({"result": "error"});
    }
    mail.sendMail(req.body.contactName, req.body.contactEmail, req.body.contactSubject, req.body.contactMessage);
    return res.status(200).type('json').send({"result":"okay"});
});

Then your frontend should work as expected. For most of the case, you don't need to specify dataType, because ajax could determine the mime type automatically base on your server response.

Enix
  • 4,415
  • 1
  • 24
  • 37