AJAX communication with pure JS and PHP I'm looking for a good approach to AJAX communication using only pure JS and PHP. I would like it to be as safe as possible and compatible with most modern browsers and IE 10+. I did some research and found some code examples for writing a vanilla JS function to handle AJAX communication, but I was not sure how safe and up to date those were. I started coding my own solution based on what I've found. I need to receive and send data using AJAX. There will be a login system and also a text posting system.

index.html

&lt;input type="checkbox" id="agreement"/&gt; I agree with terms.

&lt;input type="text" id="user"/&gt; User

&lt;input type="password" id="password"/&gt; Password

&lt;textarea id="text"&gt;&lt;/textarea&gt; Text

&lt;button id="submit" onclick="submit_form()"&gt;Submit&lt;/button&gt;

&lt;span id="result"&gt;&lt;/span&gt;


ajax.php

if($_GET['action'] == 'submit_form')
{
    $agreement = $_POST['agreement'];
    $user = $_POST['user'];
    $password = $_POST['password'];
    $text = $_POST['text'];

    echo 'Data received: &lt;br/&gt;';
    echo 'Agreement: '.$agreement.'&lt;br/&gt;';
    echo 'User: '.$user.'&lt;br/&gt;';
    echo 'Password: '.$password.'&lt;br/&gt;';
    echo 'Text: '.$text.'&lt;br/&gt;';
}


scrip.js

function submit_form()
{
    var ajax = new XMLHttpRequest();

    ajax.open('POST', 'ajax.php?action=submit_form', true);

    ajax.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

    var content = '';

    content = content + 'agreement=' + document.querySelector('#agreement').checked;
    content = content + '&amp;user=' + document.querySelector('#user').value;
    content = content + '&amp;password=' + document.querySelector('#password').value;
    content = content + '&amp;text=' + document.querySelector('#text').value;

    ajax.send(content);

    ajax.onreadystatechange = function()
    {
        if (ajax.readyState == 4 &amp;&amp; ajax.status == 200)
        {
            document.querySelector('#result').innerHTML = ajax.responseText;
        }
    }
}


Can you spot any problems with this approach? Are there better, simpler or more cross-browser compatible ways for doing the same? Are there any special concerns I should have when sending and receiving passwords?
var ajax = new XMLHttpRequest();

ajax.open('POST', 'ajax.php?action=submit_form', true);


You can replace XHR with fetch. While XHR is widely supported, fetch is easier to work with. It uses promises instead of callbacks, which means you can readily use async/await with it. It's inspired from jQuery's $.ajax(). So if you're familiar with that, fetch will just click.

var content = '';

content = content + 'agreement=' + document.querySelector('#agreement').checked;
content = content + '&amp;user=' + document.querySelector('#user').value;
content = content + '&amp;password=' + document.querySelector('#password').value;
content = content + '&amp;text=' + document.querySelector('#text').value;


Do not build query strings manually. The issue is that in query strings, certain characters must be escaped correctly for it to be valid. Otherwise, I could stick characters in there which can make the query string invalid. Use URLSearchParams() to construct the query string.

&lt;button id="submit" onclick="submit_form()"&gt;Submit&lt;/button&gt;


Instead of using onclick on the button, use onsubmit on the form instead. This way, you can also catch someone submitting the form by pressing enter. Also, instead of inline event properties, use element.addEventListener(). This way, you can, among other things, add more than just one handler and avoid defining a global function for your event handler.

if($_GET['action'] == 'submit_form')
{
    $agreement = $_POST['agreement'];
    $user = $_POST['user'];
    $password = $_POST['password'];
    $text = $_POST['text'];

    echo 'Data received: &lt;br/&gt;';
    echo 'Agreement: '.$agreement.'&lt;br/&gt;';
    echo 'User: '.$user.'&lt;br/&gt;';
    echo 'Password: '.$password.'&lt;br/&gt;';
    echo 'Text: '.$text.'&lt;br/&gt;';
}


Not exactly sure why you'd put action in a GET parameter while everything else is in POST. Use POST all the way if you intend to POST. Also, if I recall correctly, it's up to the server to parse GET parameters in a non-GET operation. The server may choose to ignore it. This might work in PHP, but it might not work on another platform.

Also, sanitize/escape the data before printing it on the page. This looks like debugging to me, so that's fine. But never trust user input, never print arbitrary values. This can easily be used in a reflected XSS, a security issue.