CORS issue when exposing API via Wix to the public

Hi all,

I am trying to expose an API via Wix, so that I can connect another app of mine hosted in netflify to read data in WixDatabase.

I tried various method

  1. Use “Access-Control-Allow-Origin” header in my wix backend code
  2. OR, use options as suggested in options - Velo API Reference - options - Velo API Reference - Wix.com

Can anyone with similar experience share some light?
My code as followed [published in Backend]:

import { ok, badRequest, forbidden, response } from 'wix-http-functions';
import wixData from 'wix-data';

function validate(origin) {
//I used localhost for local dev, also tried to switch to my netlify endpoint
    if (origin == "http://forum.wixstudio.com" || origin == "http://localhost:4201") {
        return true;
    } else {
        return false;
    }
}

export function options_member(request) {

    let headers = {
        "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
        "Access-Control-Max-Age": "86400"
    }

    if (validate(request.headers.origin)) {
        headers["Access-Control-Allow-Origin"] = request.headers.origin;
    }
    return response({ "status": 204, "headers": headers });
}

// user should only be able to get their user data
// pass in line profile ID and verify before return
// validate API key and profile ID
export async function get_member(request){
     const options = {
        "headers": {
            "Content-Type": "application/json",
        }
    };

   if (validate(request.headers.origin)) {
        options.headers["Access-Control-Allow-Origin"] =
            request.headers.origin;
        options.headers["Access-Control-Allow-Headers"] = "Content-Type";
   }

return wixData.query("members")
.find().then(results => {
    if (results.items.length > 0) {
        options.body = {
            "items": results.items
        }
        return ok(options)
    }
})

Try adding to the headers (of the GET function):

"Access-Control-Allow-Origin": "*"

Thanks for your reply. I actually tried to do the following too:

export async function get_member(request){
  
    const options = {
        "headers": {
            "Content-Type": "application/json",
            "Access-Control-Allow-Headers": "*"
        }
    };
return wixData.query("members")
.find().then(results => {
    if (results.items.length > 0) {
        options.body = {
            "items": results.items
        }
        return ok(options)
    }
})

Errors thrown as below:

It seems like the headers setting is not taking into effect?
Am i missing anything? Below is my client code for your reference.


async function getMemberDetail(){
 
const url = 'https://gamesonly603.wixsite.com/codedsphere/_functions/member'
const response = await fetch(url, {
  method: 'GET', 
  cache: 'no-cache',
  headers: {
    'Content-Type': 'application/json'
  },
  redirect: 'follow', 
  referrerPolicy: 'no-referrer' 
});
console.log (response);
}




try moving this to a backend .jsw function and then import and call the function on the front end

@gamesonly603 try "Access-Control-Allow- Origin “: " *”

@jonatandor35 Hi J.D., sorry for the typo at my end.

I did tried with "Access-Control-Allow- Origin “: " *”

So my backend looks like



export function options_memberold(request) {
    console.log(request);

    let headers = {
        "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
        "Access-Control-Max-Age": "86400",
        "Access-Control-Allow-Origin": "*"
    }

    return response({ "status": 204, "headers": headers });
}

export function get_memberold(request){
     const options = {
        "headers": {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*"
        }
    };

return wixData.query("members")
.find().then(results => {
    if (results.items.length > 0) {
        options.body = {
            "items": results.items
        }
        return ok(options)
    }
})
}

Frontend in localhost:3000 [a local npm start typescript project] looks like

async function getMemberDetail(){

const url = 'https://gamesonly603.wixsite.com/codedsphere/_functions/memberold'
const response = await fetch(url, {
  method: 'GET', 
  cache: 'no-cache', 
  headers: {
    'Content-Type': 'application/json'
  },
  redirect: 'follow', 
  referrerPolicy: 'no-referrer' 
});
console.log (response); 
}

And I am getting the same error:

I deployed the backend code file in wix’s backend:

@amotor Thanks for your reply, not sure if I understood correctly, my frontend in this context in going to another code base not directly in wix - a typescript react frontend project that I am hosting in Netlify, or localhost:3000 in local environment.

Thus, my backend is deployed to wix using http-functions to expose APIs that my frontend project can call.

Are you suggesting that I moved the code to .jsw, and call the said method in http-functions.js?
Then my frontend code call this API exposed to the public in http-functions.js?

See my backendAPI.jsw


function validate(origin) {
    if (origin == "http://forum.wixstudio.com" || origin == "http://localhost:4201") {
        return true;
    } else {
        return false;
    }
}

export function options_member(request) {
    console.log(request);

    let headers = {
        "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
        "Access-Control-Max-Age": "86400"
    }

    if (validate(request.headers.origin)) {
        headers["Access-Control-Allow-Origin"] = request.headers.origin;
    }

    return response({ "status": 204, "headers": headers });
}

export async function get_member(request){
     const options = {
        "headers": {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*"
        }
    };


return wixData.query("members")
.find().then(results => {
    if (results.items.length > 0) {
        options.body = {
            "items": results.items
        }
        return ok(options)
    }
})

In my http-functions.js


import {get_member } from 'backend/backendAPI'

export async function get_membernew(request){

     const t = await get_member(request);
     console.log(t);

}

Error as below:

These .jsw and .js are both deployed under backend.

@gamesonly603 Does it work when you don’t use localhost? Try and see, it may help locating the problem.

Also have a read:

@jonatandor35 Unfortunately it doesn’t help, see my screenshot below


I am trying to call the API after I have deployed into netlify, current setting for origin is still a wildcard, theoretically it should, not sure why it wasn’t working - “Access-Control-Allow-Origin” : “*”

@gamesonly603 I tried https://gamesonly603.wixsite.com/codedsphere/_functions/memberold
GET
and I got 204 (No Content)

I’ve got a similar issue where “Access-Control-Allow-Origin” : “*” does not seems to be taken into account

@jonatandor35 I think you might be looking at the OPTIONS method instead, see the screenshot below

Two APIs will be called when I use options according to the velo documentations. The first one is OPTIONS, which you will get 204, note that this header has the “Access-Control-Allow-Origin” : “*” . The second API is GET, which failed, see from below


The Access-Control-Allow-Origin has been removed from this method, and ended with 400. I saw some post mentioned their headers are removed - https://www.wix.com/velo/forum/coding-with-velo/corvid-stripping-cors-headers . Not sure if they are related.