且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用CORS Pre-flight请求处理自定义标头? AJAX - CodeIgniter

更新时间:2021-12-19 08:12:52

你在用 Access-Control-Allow-Headers


用于响应预检请求,以指示在发出实际请求时可以使用哪些HTTP头

Used in response to a preflight request to indicate which HTTP headers can be used when making the actual request.

尝试将以下标题添加到预检代码中。

Try adding the following header to your preflight code.

header("Access-Control-Allow-Headers: content-type, origin, accept, X-API-KEY");

我记得有类似的问题,似乎还记得其中一些也是浏览器特定的......

I recall having similar issues, seem to recall some of it being browser specific too...

如果有帮助,这里有一些我认识的代码片段:

If it helps here is a snippet from some code I know works:

// CORS and other headers.  Make sure file is not cached (as it happens for example on iOS devices)
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Max-Age: ' . CORS_AUTH_MAX_AGE);

//CORS preflight
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

    header("Access-Control-Allow-Headers: content-type, origin, accept, x-app-sig");

    $acrh = explode(',', strtolower($headers['Access-Control-Request-Headers']));
    foreach ($acrh as $k => $v) {
        $acrh[$k] = trim($v);
    }

    if (! isset($headers['Access-Control-Request-Headers']) || ! in_array('x-app-sig', $acrh)) {
        _log($h, '*** Bad preflight!' . PHP_EOL . print_r($headers, true) . PHP_EOL . print_r($_REQUEST, true));
        header("HTTP/1.1 401 Unauthorized");
        exit; //->
    }

    _log($h, '+++ Successful preflight.' . PHP_EOL . print_r($headers, true) . PHP_EOL . print_r($_REQUEST, true));
    exit; //->
}

//Now we are past preflight.  Actual Auth happens here, I check a signature that I post with payload.

更新好的,我想我现在更了解你的问题。发布了更多代码。首先,是的,我们在那里做的基本相同。我只是检查预检是否试图按标题列出它应该具有的内容。

Update: OK, think I better understand your question now. Posted a bit more code. First off, yes, we are doing essentially the same thing there. I just check that the preflight tried to white-list what it should have in terms of headers.

我认为您缺少的部分是预检应该/不会拥有您要发送的自定义标头。请参阅此处的答案:如何您是否在跨域(CORS)XMLHttpRequest中发送自定义标头?)。就像我一样,您可以检查 Access-Control-Request-Headers:是否与预检一起发送,但是您不应该检查该呼叫上是否存在实际的标头。

I think the part you are missing is that the preflight should/will not have the custom header you are trying to send. See the answer here: How do you send a custom header in a cross-domain (CORS) XMLHttpRequest?). So like I do you could check that the Access-Control-Request-Headers: are sent with the preflight, but you should not check for the actual header being present on that call.

听起来你只需要在服务器端移动一些代码 - 让预检相当香草和愚蠢,然后进行实际验证或检查自定义标题成功预检后。

Sounds like you just need to move a little of the code around server side - make the preflight pretty vanilla and dumb, then do your actual auth or checking of custom headers after successful preflight.

我使用自带有效负载的HMAC签名来验证预检后的事情。我还检查是否提供了自定义x-app-sig,虽然这可能是多余的。

I use a HMAC signature sent with the payload myself to authenticate things after the preflight. I also check that the custom x-app-sig is supplied and what i expect though that is probably redundant.