403 when trying to reference backend function

I’m writing a vendor-specific extension from my site, and I’m running into a persistent HTTP403 when trying to reference a backend function. I have the following running in my FE component:

// For Velo API Reference documentation visit http://wix.to/94BuAAs
// To learn about widget code visit https://www.wix.com/app-builder/home/resources
import 'wix-window';
import { fetch } from 'wix-fetch';

import { loadScript } from 'backend/load-stub.jsw';

$w.onReady(async function () {
    console.log("Loading translation loader...");
    const scriptResponse = await loadScript();
    const scriptText = await scriptResponse.text();

    console.log("Injecting translation loader...")
    const $stubContainer = $w('#stubContainer');
    $stubContainer.postMessage(scriptText);
});

$widget.onPropsChanged((oldProps, newProps) => {
    // If your widget has properties, onPropsChanged is where you should handle changes to their values.
    // Property values can change at runtime by code written on the site, or when you preview your widget here in the App Builder.

});

and I have this in my backend/load-stub.jsw file:

import { fetch } from 'wix-fetch';
import { fetchProjectCode } from 'backend/fetch-project-code.jsw';

export function loadScript() {
    console.log("Retrieving project code...");
    return fetchProjectCode().then(projectCode => {
        if (projectCode) {
            console.log(`Retrieved project code ${projectCode}...`);
            console.log("Loading stub...");
            return fetch(`URL HERE`).then(response => response.text());
        }
        console.error("Could not retrieve project code!");
        return null;
    });
}

However, I’m persistently getting a 403 error when the service worker tries to call loadScirpt.ajax, and I have no idea why that might be. I can’t even seem to find the Permissions dialog that in the Blocks editor that other posts are referencing.

Is this the actual code or a removed URL?

The code also needs to return objects wrapped in a response like ok() or badRequest() rather than just the raw fetch/null responses you have here.
ex: ok - Velo API Reference - Wix.com

Oh, it’s a censored URL, not the actual.
I’ll try wrapping the return value, and see how that works. Thanks for the pointer!

Nope, no difference :frowning:

The loadScript.ajax call from the service worker is still getting a 403.
Also, it might be a misunderstanding on my part, but I don’t see why I’d need to import from the wix-http-functions and return response objects in this case. I have a similar backend function in backend/fetch-project-code.jsw with the following contents - censored, of course - that’s working just fine when called from a Dashboard Page context:

import wixData from 'wix-data';

export function fetchProjectCode() {
    console.log("Querying for project code...");
    return wixData.query('@path/to/collection').ge('projectCode', "").find()
    .then(results => {
        console.log(`Retrieved ${results.length} items...`);
        if (results.items.length > 0) {
            return results.items[0].projectCode;
        }
        return null;
    })
    .catch(error => {
        console.error('Error querying for project code:', error.message);
        throw error;  // re-throw the error to ensure it's not swallowed
    });
}

The associated Dashboard page has the following Velo logic bound:

// For Velo API Reference documentation visit http://wix.to/94BuAAs
import wixDashboard from 'wix-dashboard';
import { storeProjectCode } from 'backend/store-project-code.jsw';
import { fetchProjectCode } from 'backend/fetch-project-code.jsw';

$w.onReady(async function () {
    $w('#save').onClick(async function () {
        const inputValue = $w('#projectCodeInput').value;
        try {
            await storeProjectCode(inputValue);
            console.log('Input value saved successfully');
        } catch (error) {
            console.error('Error saving input value:', error.message);
        }
    });

    console.log("Loading project code to populate input...");
    try {
        var projectCodeFromBackend = await fetchProjectCode();
    } catch (error) {
        console.error('Error fetching project code:', error.message);
        return; // exit early on error
    }

    console.log(`Fetched project code ${projectCodeFromBackend}...`);
    $w("#projectCodeInput").value = projectCodeFromBackend;
});

I’m sending raw objects back, but for some reason, the Dashboard page works and the component’s code doesn’t, which is what I’m having trouble fathoming…

I see, my misunderstanding.

Some things to check:

  • Anything in the site event logs showing other errors?
  • What happens when you do the same fetch of your URL HERE outside of the Wix site?

So I’m picking this back up (our partner asked to allocate time on this), and I checked your recommendations.

The Site Events is not showing any errors, not even the 403 that’s visible in the Chrome DevTool. If I catch and log the error explicitly, it does show up in the Site Events screen, but doesn’t include any more information, just that Request failed with status code 403.

When I try to fetch the URL from outside the function context, I get a CORS error - unless I set mode: "no-cors" - which is not correct, but in my mental model, it doesn’t explain the 403 response. everything works just fine, so I don’t think the 403 is related to the remote response. Not to mention that none of the loglines in the backend module show up, which leads me to believe that the execution doesn’t even reach that point.

Unless of course, Wix’s backend swallow’s the error and converts it into a 403 response…?

What I tried just now is to add the same logic in a public JS module, instead of the component code, but the result is the same, a 403 response from the Velo BE.
If, however, I hardwire the fetch logic into the component, it works beautifully…

1 Like