如何为CORS使用PHP代理?
我正在尝试使用一个天气API,它以xml格式返回数据。我曾使用第三方代理服务器解决CORS问题,但该服务已不再运行。我使用jquery/ajax获取如下数据:如何为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},
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部分