-1

i am testing from frontend post data to backend wordpress (woocommerce) to create customers account. i tested with postman and it works awesome but if i post data from frontend to backend i have a cross-origin issue.

i know cross-origin issue is 2 domain prevent to share resource but i tried kind alot way but still cant get the problem fix. anyone have any idea how should i solve this ?

Error :

Cross Origin Problem Refused to set unsafe header "User-Agent" from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

nuxt.js / pages / register.vue

 import {
        createWooComCustomer
    } from '@/plugins/woocomapi.js'
    export default {
        data() {
            return {
                email: '',
                username: '',
                password: ''
            }
        },
        methods: {
            async registerUsers() {
                await createWooComCustomer(this.email, this.username, this.password).then((response) => {
                    console.log(respons)
                }).catch((e) => {
                    throw new Error('failure create customer')
                })
            },
        },
        mounted() {}
    }

nuxt.js / plugins / woocomapi.js (using woocommerce/woocommerce-rest-api package)

import WooCommerceRestApi from "@woocommerce/woocommerce-rest-api";

// local test api
const api = new WooCommerceRestApi({
    url: "http://localhost:3080",
    consumerKey: "ck_xxx",
    consumerSecret: "cs_xxx",
    version: "wc/v3",
});


// fetch all products from WooCommerce //
export async function fetchWooComProducts() {
    try {
        const response = await api.get("products");
        return response
    } catch (error) {
        throw new Error(error);
    }
}

export async function createWooComCustomer(customer_email, customer_username, customer_password) {
    try {
        const response = await api.post("customers", {
            data: {
                email: customer_email,
                username: customer_username,
                password: customer_password
            }
        })
        return response
    } catch (error) {
        throw new Error(error);
    }
}

wordpress / .htaccess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</IfModule>
# END WordPress

wordpress / wp-content / themes / twentytwentyone / functions.php

add_action( 'init', 'handle_preflight' );
function handle_preflight() {
    $origin = get_http_origin();
    if ( $origin == 'http://localhost:3000/' ) {
        // You can set more specific domains if you need
        header("Access-Control-Allow-Origin: " . $origin);
        header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
        header("Access-Control-Allow-Credentials: true");
        header( 'Access-Control-Allow-Headers: Authorization' );

        if ( 'OPTIONS' == $_SERVER['REQUEST_METHOD'] ) {
            status_header(200);
            exit();
        }
    }
}

i did a restful api logs, when postman successful create it was request "POST" but this one always send as "GET" and fail to create even i am sure is post i am sending. i tried to put nginx on allow-origin "*" also tried put into apcache server directly but none of them work, being stuck for 3 days and i ran out of idea how to fix this one, if anyone got some good advice after looking at the code, please share with me, will be greatful.

here is my full repo : https://github.com/differentMonster/woonuxtpress

user8566930
  • 103
  • 1
  • 16
  • Your attempt to detect OPTIONS in the .htaccess probably comes too late - unless the request was for a physically existing file or folder, `RewriteRule . /index.php [L]` will have already rewritten it, and the L flag ends processing after that. – CBroe Jan 12 '22 at 07:11
  • `if ( $origin == 'http://localhost:3000/' )` - I don't think there is a trailing slash at the end of the origin. – CBroe Jan 12 '22 at 07:11
  • @CBroe i remove the slash before too, samething, you mean i should call the RewriteCond %{REQUEST_METHOD} OPTIONS before /index.php [L] – user8566930 Jan 12 '22 at 09:17
  • Yes, it would need to come before that, to take any effect. – CBroe Jan 12 '22 at 09:21
  • @CBroe i switch the RewriteRule . /index.php [L] to top of the {REQUEST_METHOD} OPTIONS and wordpress frontend has some werid behaviour, also didt work at all. – user8566930 Jan 14 '22 at 05:41
  • @Cbroe but i found a person plugins in that save my life. https://github.com/mandrasch/wp-configure-cors-origin – user8566930 Jan 14 '22 at 05:42
  • @CBroe really greatful for you advice :D, but your advice help me on other part that make my .htaccess cleanner now, thank you mate. – user8566930 Jan 14 '22 at 05:45

1 Answers1

-1

wordpress / wp-content / themes / the theme that your wordpress select / functions.php

function handle_preflight()
{
    // set header for rest API (and other resources as well?)
    header("Access-Control-Allow-Origin: " . "*");
    header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
    header("Access-Control-Allow-Credentials: true");
    header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
    if ('OPTIONS' == $_SERVER['REQUEST_METHOD']) {
        status_header(200);
        exit();
    }
}

add_action('init', __NAMESPACE__ . '\handle_preflight');

remove the if check $origin and if you have any 'POST or 'PUT' on the if 'POST' == $_SERVER['REQUEST_METHOD'] switch to 'OPTIONS' cause OPTIONS is more widely accpeting all.

if you are wondering should you change the CORS on the server or the .htaccess, just focus on the wordpress part, cause me trying all part to see anything work, it will make more chaos. keep your hatcess simple as possible.

wordpress / .htacess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

also no need to send anything header from frontend or nginx, on the js part remove the data object, somehow woocommerce rest api is accpeting without the object data wrap.

nuxt.js / plugins / woocomapi.js

 try {
        const response = await api.post("customers", {
                email: customer_email,
                username: customer_username,
                password: customer_password
        })
        return response
    } catch (error) {
        throw new Error(error);
    }
user8566930
  • 103
  • 1
  • 16
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 14 '22 at 11:34
  • Why is this -1? Was that -1 added before the edit? – Patryk Chowratowicz 'Zszywacz' Feb 23 '23 at 15:04