I have successfully created a new endpoint/route and can view it via wp-json
. Not only that, I can successfully make a post request to this endpoint externally from the browser using the Restlet Client. My endpoint handles json
within the body of the request, transforms and edits the data, then makes an external api call, then sends new data back to the client from the external api.
However, when I run an application on my wordpress site that calls this api, I get 400 Bad Request
. I handle errors in many places within my function, and send back specific error messages based on types of errors that can occur in the data and I can't seem to find where this is coming from. I have set WP_DEBUG
to true
, and I'm stuck.
I think it may have to do with handling the pre-flight
request but not sure.
Can you help me find the error?
PreFlight Handling
function handle_preflight() {
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); //HTTP 1.1
header("Pragma: no-cache"); //HTTP 1.0
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Access-Control-Allow-Origin: *"); // change * to the known origin once this is put into place
header("Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
header('Access-Control-Max-Age: 50');
header("Content-Type: application/json");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type");
http_response_code(200);
exit();
}
}
add_action( 'init', 'handle_preflight' );
Init REST endpoint
add_action( 'rest_api_init', function() {
$version = '1';
$namespace = "cbngiving/v".$version;
$base = "giving";
register_rest_route( $namespace, "/" . $base, array(
'methods' => 'POST, OPTIONS',
'callback'=> 'proxy_data'
));
});
CALLBACK
function proxy_data($request) {
$data = $request->get_json_params();
if(is_null($data)) {
$response = new WP_REST_Response(array('statusText' => "Bad Request - Your request is missing parameters. Please verify and resubmit.",
"origin" => "Bad Request from App to Proxy"));
$response->set_status(400);
return $response;
} else {
$mode = $data['mode'];
$data['APIAccessID'] = ''; // to be added later
$data['UrlReferrer'] = $_SERVER["HTTP_REFERRER"];
$data['ClientBrowser'] = $_SERVER["HTTP_USER_AGENT"];
$service_url_local = "PRIVATE ENDPOINT< NOT CAUSING ERROR!";
$service_url_secure = "PRIVATE ENDPOINT< NOT CAUSING ERROR!";
$service_url = $mode === "production" ? $service_url_secure : $service_url_local;
unset($data['mode']);
$proxy_response = wp_remote_post($service_url, array(
'headers' => array(
'Content-Type' => 'application/json; charset=utf-8',
'Accept' => 'application/json; charset=utf-8'
),
'body' => json_encode($data)
));
$proxy_response_code = wp_remote_retrieve_response_code( $proxy_response );
$proxy_response_body = wp_remote_retrieve_body( $proxy_response );
if ($proxy_response_code >=200 and $proxy_response_code < 300) {
$response = new WP_REST_Response($proxy_response_body);
$response->set_status(201);
return $response;
} else {
$error = json_decode($proxy_response_body, TRUE);
$response = new WP_REST_Response(array("statusText" => $error, "origin" => "Error Response from Giving Services"));
$response->set_status($proxy_response_code);
return $response;
}
}
}
UPDATED TO INCLUDE API CALL FROM REACT APPLICATION
I'm using the Fetch Api
within a React Application that is being added to the page via a script.
fetch(proxy, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(checkStatus)
.then(parseJSON)
.then(json=>{
const msg = json;
self.props.submitForm({msg, data})
}).catch(error=>{
logError({error});
this.setState({submitting: false})
});
HELPER FUNCTIONS
function logError({error}) {
console.error(JSON.stringify(error, null, 5))
if (error.status >= 500) {
alert('There was an internal error submitting your form. Please check your information and try again or call us at PRIVATE');
}
}
function checkStatus(response) {
console.log({response})
if (response.status >= 200 && response.status < 300) {
return response
} else {
var error = new Error(response.statusText)
error.response = response
error.status = response.status
throw error
}
}
function parseJSON(response) {
return response.json()
}
handle_preflight()
(comment out theadd_action()
)? Does the 400 error persist?is_null($data)
in theproxy_data()
function. Try temporarily change the$response->set_status(400);
to$response->set_status(200);
(or use another status other than400
).. and see if you get the200
status. If yes, then the problem was probably with the request body.