400错误请求-JavaScript应用程序调用自定义wp-json终结点

时间:2018-09-26 作者:wlh

我已成功创建了新的端点/路由,可以通过wp-json. 不仅如此,我还可以使用Restlet客户端从浏览器外部成功地向该端点发出post请求。我的端点句柄json 在请求主体内,转换和编辑数据,然后进行外部api调用,然后从外部api将新数据发送回客户端。

然而,当我在wordpress站点上运行调用此api的应用程序时,我得到400 Bad Request. 我处理函数中许多地方的错误,并根据数据中可能出现的错误类型发回特定的错误消息,但我似乎找不到这些错误的来源。我已设置WP_DEBUGtrue, 我被困住了。

我认为这可能与处理pre-flight 请求但不确定。

你能帮我找到错误吗?

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

我正在使用Fetch Api 在通过脚本添加到页面的React应用程序中。

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()
}

1 个回复
最合适的回答,由SO网友:wlh 整理而成

我在上面的代码中发现了三个问题。

第一$_SERVER["HTTP_REFERRER"]; 是一个未定义的索引,而且它是错误的-HTTP_REFERER 如果可以在WP中以这种方式访问,则是正确的。我发现get_http_origin() 相反

$data[\'UrlReferer\'] = get_http_origin();
其次,我还将保存此变量的字段错误地放在了-UrlReferrer (坏),UrlReferer (正确),只有我自己通过测试才能检测到。但是如果我没有抓住第一个,我就不会抓住这个。

第三,我放弃了$data[\'ClientBrowser\'] = $_SERVER["HTTP_USER_AGENT"]; 因为我可以得到客户端。

UPDATE

我还可以从客户端通过window.location.href 到api。

结束