Friday, February 6, 2026

Easy AI with Javascript

For an index to all my stories click this text.

This story shows how to create a webpage in HTML with some Javascript that sends a question to a simple AI system and puts the answer on the webpage. No account or login is needed.

In a previous story I told you how you could send a question to an AI system with Micropython on a Microcontroller like the Raspberry Pi Pico or ESP32. The answer that the AI produced was shown in Thonny's shell.
I have a fun project coming up with that. In the meantime you can read that story here:
https://lucstechblog.blogspot.com/2026/01/easy-ai-with-micropython.html

This time we are going to do the same on a webpage. The page is made with some simple HTML and Javascript.

We are going to use the same API as was used in the MicroPython program. Of course the syntax will be a bit different and there is a small caveat which we need to address.

The program

I started with the following program. 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Simple AI Fetch</title>
</head>
<body>
  <h2>Ask a Question</h2>
  <input id="userInput" type="text" placeholder="Type your question..." size="50">
  <button onclick="sendRequest()">Send</button>

  <h3>Response:</h3>
  <pre id="output"></pre>

<script>
function sendRequest() {
  const userText = document.getElementById("userInput").value.trim();

  const targetUrl = "http://nimaartman.ir/science/L1.php?text=" +
    encodeURIComponent("answerinenglishnoutf8anywhere.:" + userText);

  fetch(targetUrl)
    .then(function(response) {
      return response.text(); // convert to text
    })
    .then(function(text) {
      document.getElementById("output").textContent = text; // display the response
    })
    .catch(function(error) {
      document.getElementById("output").textContent = "Error: " + error;
    });
}
</script>
</body>
</html>

The code looks and is simple. Here are some points that might interest you.

  const userText = document.getElementById("userInput").value.trim();

  const targetUrl = "http://nimaartman.ir/science/L1.php?text=" +
    encodeURIComponent("answerinenglishnoutf8anywhere.:" + userText);

The question we are going to send to the AI is fetched from the input field (input id="userInput") and put int the userText variable.

Then the URL is formed which basically is:
http://nimaartman.ir/science/L1.php?text=userText

  fetch(targetUrl)
    .then(function(response) {
      return response.text(); // convert to text
    })
    .then(function(text) {
      document.getElementById("output").textContent = text; // display the response
    })
    .catch(function(error) {
      document.getElementById("output").textContent = "Error: " + error;
    });

Then the fetch command sends the targetURL.
Next the answer from the AI is in the response and just the text is distilled from that. And then that text is put in the output field.
And lastly there is a function that catches errors.

And yes I got an error !!!


The dreadful CORS error.

MicroPython did not give that error because it does not act as a webpage. But here a webpage is trying to access the API and that causes the CORS error.

The solution

Luckily I stumbled sometime ago upon a websrvice called AllOrigins.
You can find it here: https://allorigins.win/

I wrote a story about this some time ago you can find it here.
https://lucstechblog.blogspot.com/2026/01/solving-cors-error-with-javascript.html

Basically it works like this.
You want to send a fetch command. You wrap this fetch command in the AllOrigins API and then AllOrigins takes care of the CORS error.

So what we need to do is to wrap our fetch command into the AllOrigins API and here is how it's done:

  const targetUrl = "http://nimaartman.ir/science/L1.php?text=" +
    encodeURIComponent("answerinenglishnoutf8anywhere.:" + userText);

  const proxyUrl = "https://api.allorigins.win/raw?url=" + encodeURIComponent(targetUrl);

First step is to create the targetURL which is the same as we did in the previous program. But then we wrap it in the AllOrigins API and put it in the variable proxyURL.
And then proxyURL is send to the Ai with the fetch command.

So here is the complete program:

<!DOCTYPE html>
<html lang="en">

<body>
  <h2>Ask a Question</h2>
  <input id="userInput" type="text" placeholder="Type your question..." size="50">
  <button onclick="sendRequest()">Send</button>

  <h3>Response:</h3>
  <pre id="output"></pre>

<script>
function sendRequest() {
  const userText = document.getElementById("userInput").value.trim();

  const targetUrl = "http://nimaartman.ir/science/L1.php?text=" +
    encodeURIComponent("answerinenglishnoutf8anywhere.:" + userText);

  const proxyUrl = "https://api.allorigins.win/raw?url=" + encodeURIComponent(targetUrl);

  fetch(proxyUrl)
    .then(function(response) {
      return response.text(); // convert to text
    })
    .then(function(text) {
      document.getElementById("output").textContent = text; // display the response
    })
    .catch(function(error) {
      document.getElementById("output").textContent = "Error: " + error;
    });
}
</script>
</body>
</html>

The result.

Well it does work.


The program is simple so the answer is displayed but you will have to scroll through the page to get the full text.
That is OK but the real program lies in all the extra code that is send along like this: "data":"\ud83c\udf0d\ud83d\udd04

So best thing is to filter every strange code out.
And I wanted to make the input and output fields variable in width.

So here is the complete code which takes care of these issues:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Simple AI Fetch</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 2rem;
      max-width: 800px;
      display: flex;
      flex-direction: column;
      gap: 1rem;
    }

    h2, h3 {
      margin-bottom: 0.5rem;
    }

    textarea {
      width: 100%;
      min-height: 100px;
      padding: 10px;
      font-size: 16px;
      line-height: 1.4;
      resize: vertical; /* allow user to resize vertically */
      box-sizing: border-box;
      word-wrap: break-word;
    }

    button {
      width: 120px;
      padding: 10px;
      font-size: 16px;
      cursor: pointer;
    }

    #output {
      width: 100%;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 5px;
      background-color: #f9f9f9;
      white-space: pre-wrap; /* preserves line breaks and wraps long lines */
      word-wrap: break-word;
      font-size: 16px;
      line-height: 1.4;
      min-height: 50px;
    }

    @media (max-width: 600px) {
      body {
        margin: 1rem;
      }
      textarea, #output {
        font-size: 15px;
      }
    }
  </style>
</head>
<body>
  <h2>Ask a Question</h2>
  <textarea id="userInput" placeholder="Type your question..."></textarea>
  <button onclick="sendRequest()">Send</button>

  <h3>Response:</h3>
  <div id="output"></div>

  <script>
    async function sendRequest() {
      const userText = document.getElementById("userInput").value.trim();
      if (!userText) return alert("Please enter a question!");

      const targetUrl = "http://nimaartman.ir/science/L1.php?text=" +
                        encodeURIComponent("answerinenglishnoutf8anywhere.:" + userText);

      const proxyUrl = "https://api.allorigins.win/raw?url=" + encodeURIComponent(targetUrl);

      try {
        const response = await fetch(proxyUrl);
        const text = await response.text();

        let data;
        try {
          data = JSON.parse(text);
        } catch {
          data = { data: text };
        }

        let rec_ans = data.data || "";
        rec_ans = rec_ans.replace(/[^A-Za-z0-9 \n.,!?\\*+\-%@$&:<>()[\]{}"`]/g, "");
        rec_ans = rec_ans.trim();

        document.getElementById("output").textContent = rec_ans;
        console.log("Received Answer:", rec_ans);

      } catch (err) {
        console.error("Fetch error:", err);
        document.getElementById("output").textContent = "Error: " + err.message;
      }
    }
  </script>
</body>
</html>


To use this program just copy it. Then paste it in an editor and save it as AI-test.html. Then open the folder where you saved it and just click on the icon. Your web-browser will open with the program.

The code is extended by CSS to make the in and output fields changeable in width and it filters all non-ascii characters out.

And boy does it work !!!


Here is an example in which I asked what the circumfence of the earth is. AI even corrected my spelling mistake....


And here I asked about one of my favorite books: When HARLIE was one written by David Gerrold.

This works.
Now I have an idea for something fun. But that's for next time.

Sidenote

This program is made in HTML with some Javascript. Javascript is an easy to learn language that works in your browser and gives direct results in your browser, and therefore on your computer screen. Javascript works almost on any system I know. It works on Linux and on Windows systems and these can be PC's as well as Raspberry Pi's.

Javascript is an extensive language and therefore suitable for many projects. To make things simple I gathered more then 500 tips for working with all aspects of Javascript. I published these in a book that can world wide be bought through Amazon.

You can get more information or buy the book by clicking this text.

Caveats

There are some things to consider.

This is a free service to access AI but it is not documented how many API call's you are allowed to make for free.
It is also unknown what AI they are using, is it Copilot ?, ChatGPT ?, Gemini ? no idea really.
The API is run by nimaartman.ir So they are located in Iran (Persia). But their website does not give any further information beside that they are into game programming.
So basically we have no information about the company that is running this show. And we can not be sure how long this service will continue to exist.

So please consider these points before using this service in some real long lasting projects.

Considering this I started working on another service to use AI in my projects. And I found one. But until I fully worked it out this method works great and is fun to play with.

Till next time.
Have fun


Luc Volders