如何为CORS使用PHP代理?

如何为CORS使用PHP代理?,php,jquery,ajax,Php,Jquery,Ajax,我正在尝试使用一个天气API,它以xml格式返回数据。我曾使用第三方代理服务器解决CORS问题,但该服务已不再运行。我使用jquery/ajax获取如下数据: function getMetarToTable(){ var stationt="KJFK"; $.ajax({ type: "GET", url: 'proxy.php', crossDomain: true, data: {'stationString': stationt},

我正在尝试使用一个天气API,它以xml格式返回数据。我曾使用第三方代理服务器解决CORS问题,但该服务已不再运行。我使用jquery/ajax获取如下数据:

function getMetarToTable(){
    var stationt="KJFK";
    $.ajax({
    type: "GET",
    url: 'proxy.php',
    crossDomain: true,
    data: {'stationString': stationt},
    datatype: "xml",
    headers: {
        'X-Proxy-URL': 'https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25',
    },
    error: function(jqXHR, textStatus, errorThrown) {
    console.log('Error: ' + errorThrown);
    },
       success: function(xml) {
       $("#metarweatherpage").html('');
       $(xml).find('METAR').each(function(){

      var sRawtext = $(this).find('raw_text').text();
      var sStationid = $(this).find('station_id').text();
      $("#metarweatherpage").append('<p><h2>'+sStationid+'</h2></p><p>'+sRawtext+'</p>');

     });
     },

    });

};
函数getMetarToTable(){ var stationt=“KJFK”; $.ajax({ 键入:“获取”, url:'proxy.php', 跨域:是的, 数据:{'stationString':stationt}, 数据类型:“xml”, 标题:{ “X-Proxy-URL”:”https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25', }, 错误:函数(jqXHR、textStatus、errorshown){ log('Error:'+errorshown); }, 成功:函数(xml){ $(“#metarweatherpage”).html(“”); $(xml).find('METAR').each(function(){ var sRawtext=$(this).find('raw_text').text(); var sStationid=$(this).find('station_id').text(); $(“#metarweatherpage”).append(“”+sStationid+”

“+sRawtext+”

”); }); }, }); }; PHP-proxy.PHP

    <?php
    if( ! isset($whitelist))
        $whitelist = [];
    if( ! isset($curl_maxredirs))
        $curl_maxredirs = 10;
    if( ! isset($curl_timeout))
        $curl_timeout = 30;
    // Get stuff
    $headers = getallheaders();
    $method = __('REQUEST_METHOD', $_SERVER);
    $url = __('X-Proxy-Url', $headers);
    $cookie = __('X-Proxy-Cookie', $headers);
    // Check that we have a URL
    if( ! $url)
        http_response_code(400) and exit("X-Proxy-Url header missing");
    // Check that the URL looks like an absolute URL
    if( ! parse_url($url, PHP_URL_SCHEME))
        http_response_code(403) and exit("Not an absolute URL: $url");
    // Check referer hostname
    if( ! parse_url(__('Referer', $headers), PHP_URL_HOST) == $_SERVER['HTTP_HOST'])
        http_response_code(403) and exit("Invalid referer");
    // Check whitelist, if not empty
    if( ! empty($whitelist) and ! array_reduce($whitelist, 'whitelist', [$url, false]))
        http_response_code(403) and exit("Not whitelisted: $url");
    // Remove ignored headers and prepare the rest for resending
    $ignore = ['Cookie', 'Host', 'X-Proxy-URL'];
    $headers = array_diff_key($headers, array_flip($ignore));
    if($cookie)
        $headers['Cookie'] = $cookie;
    foreach($headers as $key => &$value)
        $value = "$key: $value";
    // Init curl
    $curl = curl_init();
    do
    {
        // Set generic options
        curl_setopt_array($curl, [
                CURLOPT_URL => $url,
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_HEADER => TRUE,
                CURLOPT_TIMEOUT => $curl_timeout,
                CURLOPT_FOLLOWLOCATION => TRUE,
                CURLOPT_MAXREDIRS => $curl_maxredirs,
            ]);
        // Method specific options
        switch($method)
        {
            case 'HEAD':
                curl_setopt($curl, CURLOPT_NOBODY, TRUE);
                break;
            case 'GET':
                break;
            case 'PUT':
            case 'POST':
            case 'DELETE':
            default:
                curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
                curl_setopt($curl, CURLOPT_POSTFIELDS, file_get_contents('php://input'));
                break;
        }
        // Perform request
        ob_start();
        curl_exec($curl) or http_response_code(500) and exit(curl_error($curl));
        $out = ob_get_clean();
        // HACK: If for any reason redirection doesn't work, do it manually...
        $url = curl_getinfo($curl, CURLINFO_REDIRECT_URL);
    }
    while($url and --$maxredirs > 0);
    // Get curl info and close handler
    $info = curl_getinfo($curl);
    curl_close($curl);
    // Remove any existing headers
    header_remove();
    // Use gz, if acceptable
    ob_start('ob_gzhandler');
    // Output headers
    $header = substr($out, 0, $info['header_size']);
    array_map('header', explode("\r\n", $header));
    // And finally the body
    echo substr($out, $info['header_size']);
    // Helper functions
    function __($key, array $array, $default = null)
    {
        return array_key_exists($key, $array) ? $array[$key] : $default;
    }
    function whitelist($carry, $item)
    {
        static $url;
        if(is_array($carry))
        {
            $url = parse_url($carry[0]);
            $url['raw'] = $carry[0];
            $carry = $carry[1];
        }
        // Equals the full URL
        if(isset($item[0]))
            return $carry or $url['raw'] == $item[0];

        // Regex matches the full URL
        if(isset($item['regex']))
            return $carry or preg_match($item['regex'], $url['raw']);
        // Select components matches same components in the URL
        return $carry or $item == array_intersect_key($url, $item);
    }

参加聚会有点晚了,但很明显发生了什么事

PHP数组索引充当哈希表,因此它们区分大小写

在客户端js中,您将请求头设置为
'X-Proxy-URL':
,但是,在服务器端php中,您检查
'X-Proxy-URL'
,请注意URL与URL部分