0

This type of question has already been asked many times, but I can't find an answer that:

  1. Does not use jQuery

  2. Works

jQuery answers: https://stackoverflow.com/a/44105591, https://stackoverflow.com/a/43393223

Not jQuery, but doesn't work: https://stackoverflow.com/a/38982661

"Drop that and try jQuery"

First of all, I'm trying to do this with a browser extension.

Here is my (only) JS file:

// ...

function log(info,time){
    if(time===undefined)time=true;
    var xhttp=new XMLHttpRequest();
    xhttp.onreadystatechange=function(){
        if(this.readyState===4&&this.status===200){
            console.log(this.responseText);
        }
    }
    info="http://localhost/log.php?log_item="+encodeURIComponent(info)+"&time="+(time?"true":"false");
    xhttp.open("GET",info,true);
    xhttp.send(null);
}

// ...

Of course, this uses GET. info is a string, and time is either undefined (handled in the function) or boolean.

This is how I tried to use POST:

function log(info,time){
    if(time===undefined)time=true;
    var xhttp=new XMLHttpRequest();
    xhttp.onreadystatechange=function(){
        if(this.readyState===4&&this.status===200){
            console.log(this.responseText);
        }
    }
    info="log_item="+encodeURIComponent(info)+"&time="+(time?"true":"false");
    xhttp.open("POST","http://localhost/log.php",true);
    xhttp.send(JSON.stringify({
        "log_item":info,
        "time":time?"true":"false"
    }));
}

As taken from https://stackoverflow.com/a/38982661

And here is my log.php:

<?php
header("Access-Control-Allow-Origin: *");
if(isset($_POST["log_item"],$_POST["time"])){
    $_POST["log_item"]=urldecode($_POST["log_item"]);
    if($_POST["time"]==="true")file_put_contents("log.html","<li><b>[".date('l, F j, Y \a\t h:i:s A')."]: </b>$_POST[log_item]</li>\n",FILE_APPEND);
    else file_put_contents("log.html",$_POST["log_item"]."\n",FILE_APPEND);
    echo $_POST["time"];
}

You shouldn't have to worry about it, though. It just logs to log.html.

I can't find a working solution to this (or maybe I'm not using the working solutions correctly). And again your answer should not include jQuery.

Lakshya Raj
  • 1,669
  • 3
  • 10
  • 34
  • Did you try `xhttp.send(info);`? What you're doing there (sending URL-encoded data within a JSON object) makes no sense. – ADyson Feb 24 '21 at 00:22
  • 1
    P.s. if you're looking to do Ajax with native browser functions, the modern alternative to XMLHttpRequest is fetch(). https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API . It supports Promises (like jQuery does) and the syntax is generally saner overall. – ADyson Feb 24 '21 at 00:23
  • but did it work with jquery? check your network tab on dev tools to check for errors. – ariel Feb 24 '21 at 04:33
  • @ADyson: Can you post an answer on how I can use the solution from either/both your first and second comment? I have tried both but can't seem to get them working. – Lakshya Raj Feb 24 '21 at 14:34
  • @ariel: It does work with jQuery (I only added it because you asked), and there are no errors in either case: with or without jQuery. Without jQuery it completes the XHR but does not log anything, and with jQuery it logs everything. – Lakshya Raj Feb 24 '21 at 14:42
  • Let's just focus on fixing your code, since it should be right (or nearly right). What does `can't seem to get them working` actually mean? What have you done to try and debug it? `xhttp.send(info);` should send the data in URL-encoded format. Have you a) Used the browser's Network tool to ensure the data is send in the AJAX request in the format you expect, b) checked the browser console for any errors, and c) done something like `var_dump($_POST)` in the PHP to check what's actually submitted (it should then show up in the responseText)?Let's get some data we can use to move to the next step – ADyson Feb 24 '21 at 14:46
  • `$_POST["log_item"]=urldecode($_POST["log_item"]);` shouldn't be necessary in the PHP btw, decoding should happen automatically before it gets to this step. – ADyson Feb 24 '21 at 14:48
  • @ADyson: It is there because I have URLEncoded it from JS, so then I decode it in PHP. Also, I'm doing everything you have posted right now. Will comment the results. – Lakshya Raj Feb 24 '21 at 14:50
  • `It is there because I have URLEncoded it from JS, so then I decode it in PHP`...yes but what I'm saying is that PHP should already take care of decoding it automatically. It's _expecting_ URL-encoded data, that should be a given. You shouldn't need to manually decode it. – ADyson Feb 24 '21 at 14:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229161/discussion-between-lakshya-raj-and-adyson). – Lakshya Raj Feb 24 '21 at 14:52
  • @ADyson: You can join me [in chat](https://chat.stackoverflow.com/rooms/229161/). – Lakshya Raj Feb 24 '21 at 14:55

1 Answers1

2

What you're doing there (sending URL-encoded data within a JSON object) makes no sense. You're mixing two different data formats arbitrarily. You also haven't set the content-type header, which is needed, otherwise it defaults to plain-text/HTML and the server won't populate it into the $_POST variables.

This version will work:

function log(info,time){
    if(time===undefined)time=true;
    var xhttp=new XMLHttpRequest();
    xhttp.onreadystatechange=function(){
        if(this.readyState===4&&this.status===200){
            console.log(this.responseText);
        }
    }
    info="log_item="+encodeURIComponent(info)+"&time="+(time?"true":"false");
    
    xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); //set content type
    xhttp.open("POST","http://localhost/log.php",true);
    xhttp.send(info); //just send the URL-encoded data without wrapping it in JSON
}

P.S. $_POST["log_item"]=urldecode($_POST["log_item"]); is redundant in the PHP - the data will be decoded automatically already.

ADyson
  • 57,178
  • 14
  • 51
  • 63