Stumped - how to allow "Access-Control-Allow-Origin: *");"

I have a siteA that only seems to work if I use AJAX to access .PHP files from the same domain.

The AJAX script that works is:

const search = debounce(async (searchTerm) => 
{
    // if the search term is removed, reset the search result
    if (!searchTerm) {
      // reset the search result
      searchResultElem.innerHTML = '';
      return;
    }
 
    try {
      searchResultElem.innerHTML = '';

      // make an API request
      // THIS DOES NOT WORK - MUST BE SAME PAGE AS index.php
      // const url = 'https://domainB.com/AJAX-123.php?q=' + searchTerm;
      // 
      // FireFox Console error:
      // Cross-Origin Request Blocked: 
      // The Same Origin Policy disallows reading the remote resource 
      // at https://domainB.com/AJAX-123.php?q=lee%20child. 
      // (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

      const url      = 'AJAX-123.php?q=' + searchTerm;
      const response = await fetch(url);
        if (response.ok) { // if HTTP-status is 200-299
          // get the response body (the method explained below)
          // let json = await response.json();
        } else {
          alert("HTTP-Error: " + response.status);
        }      
      const result   = await response.text();

      // alert(result);
      // console.log(result);
      searchResultElem.innerHTML = result;
    } catch (error) {
      console.log(error);
    }
});

I have searched and read numerous articles but unfortunately still do not understand how to defeat the CORS header ‘Access-Control-Allow-Origin’ missing)

Both sites are mine and tried setting .htaccess and PHP header scripts without success :frowning:

Questions:

  1. Do I have to send a JavaScript/AJAX parameter from domainA
  2. Does DomainB need htaccess and/or a PHP header(‘Allow Cross Site Browsing’);
  3. Which error log files are updated, domainA and/or domainB

Nothing needs to change on the requesting side. The request can be made as usual.

The responding site needs to add a CORS header to the response indicating it’s fine when the other domain does a cross-site request to it.

Since this is a browser only thing, I don’t think any error logs get updated since from the server’s perspective nothing went wrong. The browser just doesn’t accept the response without CORS headers, but no server is involved in that decision, so it isn’t logged anywhere.

1 Like

I would be grateful for an example that I could try.

So here’s my first step.

In your ‘siteB’ (trex goes rawr) PHP code. Top of the script: (Remember, you have to set headers BEFORE ANY OUTPUT. No whitespace, no nothing.)

<?php
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
            header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");    
        exit(0);
}

Save file. Request file manually, and inspect the response using your browser’s Network panel. You should see the header on the response. (If you don’t, your server’s likely playing middleman games…)

Also, obligatory ‘read the spec’ disclaimer against allowing *, but whatever.

2 Likes

Many thanks , it worked a treat :slight_smile:

My problem was that I only used the first line. The GET Request was not implemented.

Unfortunately the error message received in FireFox Browser Console was quite brief. The link to further details introduced many new concepts which I could not understand.

[off-topic]
I have a Standalone siteA which uses the latest CodeIgniter4 Framework.

I was hoping to create many other websites, such as siteB, siteC, siteD, siteEtc, each with a single index.php that passes parameters to siteA

Further thoughts and now realise that only a couple of parameters need passing to the parent siteA.

Also leaving the relative path of AJAX app.js->const=‘AJAX-123.php?q=’ + searchTerm; will allow hard-coding different database and table names instead of passing and parsing numerous variables. Identically named style sheets and images can also be effectively utilised.

Separation of Concerns springs to mind :slight_smile:
[/off-topic]

Don’t use all origin *. I recommend you actually put in siteA URL in to only allow from that domain or you are letting any domain call siteB. Just a recommendation.

3 Likes

leaving the relative path of AJAX app.js->const=‘AJAX-123.php?q=’ + searchTerm; will allow hard-coding different database and table names instead of passing and parsing numerous variables. Identically named style sheets and images can also be effectively utilised.

Insert standard cautions about implementing database security, prepared queries, etc etc… leave as few variables exposed as possible - your code could determine, for example, the db to use based on the requestor’s address.

1 Like

When I’m back on the desktop I will certainly try hard coding the domai and also test the effectiveness.

The book store source contents are freely available on another site in a XLS Spreadsheet format. The MySQL database table contents are updated and entirely replaced every hour. Login details are buried in the framework above the root. I will check again and endeavour to prevent any security loopholes.

I’m more concerned with a new section that stores customer name and address details which are emailed to the client.

Watch this space :slight_smile: