使用 php 代理的跨域 Ajax GET 请求


Cross-Domain Ajax GET request with php proxy

在过去的几天里,我一直在为此拔头发。我正在尝试从公共 API 获取跨域 ajax GET 请求以工作,但我根本无法让它工作。

PHP:我正在使用Ben Alman的ba-simple-proxy (https://github.com/cowboy/php-simple-proxy)

    <?PHP
    $enable_jsonp    = false;
    $enable_native   = false;
    $valid_url_regex = '/.*/';
    $url = $_GET['url'];
    if ( !$url ) {
      // Passed url not specified.
      $contents = 'ERROR: url not specified';
      $status = array( 'http_code' => 'ERROR' );
    } else if ( !preg_match( $valid_url_regex, $url ) ) {
      // Passed url doesn't match $valid_url_regex.
      $contents = 'ERROR: invalid url';
      $status = array( 'http_code' => 'ERROR' );
    } else {
      $ch = curl_init( $url );
      if ( strtolower($_SERVER['REQUEST_METHOD']) == 'post' ) {
        curl_setopt( $ch, CURLOPT_POST, true );
        curl_setopt( $ch, CURLOPT_POSTFIELDS, $_POST );
      }
      if ( $_GET['send_cookies'] ) {
        $cookie = array();
        foreach ( $_COOKIE as $key => $value ) {
          $cookie[] = $key . '=' . $value;
        }
        if ( $_GET['send_session'] ) {
          $cookie[] = SID;
        }
        $cookie = implode( '; ', $cookie );
        curl_setopt( $ch, CURLOPT_COOKIE, $cookie );
      }
      curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
      curl_setopt( $ch, CURLOPT_HEADER, true );
      curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
      curl_setopt( $ch, CURLOPT_USERAGENT, $_GET['user_agent'] ? $_GET['user_agent'] : $_SERVER['HTTP_USER_AGENT'] );
      list( $header, $contents ) = preg_split( '/(['r'n]['r'n])''1/', curl_exec( $ch ), 2 );
      $status = curl_getinfo( $ch );
      curl_close( $ch );
    }
    // Split header text into an array.
    $header_text = preg_split( '/['r'n]+/', $header );
    if ( $_GET['mode'] == 'native' ) {
      if ( !$enable_native ) {
        $contents = 'ERROR: invalid mode';
        $status = array( 'http_code' => 'ERROR' );
      }
      // Propagate headers to response.
      foreach ( $header_text as $header ) {
        if ( preg_match( '/^(?:Content-Type|Content-Language|Set-Cookie):/i', $header ) ) {
          header( $header );
        }
      }
      print $contents;
    } else {
      // $data will be serialized into JSON data.
      $data = array();
      // Propagate all HTTP headers into the JSON data object.
      if ( $_GET['full_headers'] ) {
        $data['headers'] = array();
        foreach ( $header_text as $header ) {
          preg_match( '/^(.+?):'s+(.*)$/', $header, $matches );
          if ( $matches ) {
            $data['headers'][ $matches[1] ] = $matches[2];
          }
        }
      }
      // Propagate all cURL request / response info to the JSON data object.
      if ( $_GET['full_status'] ) {
        $data['status'] = $status;
      } else {
        $data['status'] = array();
        $data['status']['http_code'] = $status['http_code'];
      }
      // Set the JSON data object contents, decoding it from JSON if possible.
      $decoded_json = json_decode( $contents );
      $data['contents'] = $decoded_json ? $decoded_json : $contents;
      // Generate appropriate content-type header.
      $is_xhr = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
      header( 'Content-type: application/' . ( $is_xhr ? 'json' : 'x-javascript' ) );
      // Get JSONP callback.
      $jsonp_callback = $enable_jsonp && isset($_GET['callback']) ? $_GET['callback'] : null;
      // Generate JSON/JSONP string
      $json = json_encode( $data );
      print $jsonp_callback ? "$jsonp_callback($json)" : $json;
    }
    ?>

我尝试从中获取信息的API是aviationweather API。终结点网址:

https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25

j查询:

function getMetarToTable(){
        var proxy = 'simple-proxy.php',
        url=proxy + '?' +'https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25';
    var stationt="KJFK";
    $.ajax({
    type: "GET",
    url: url,
    crossDomain: true,
    data: {'stationString': stationt},
    datatype: "xml",
    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>');
     });
    },
    });
};

真的很感激我能得到的任何帮助。

来自 PHP:

$url = $_GET['url'];

它正在尝试从名为 url 的查询字符串参数读取 URL。

从 JavaScript:

url=proxy + '?' +'https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25';

您传递的是原始数据,而不将其编码为查询字符串。

为此:

var url = 'https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25'
var query = encodeURIComponent("url") + "=" + encodeURIComponent(url);
var proxy_url = proxy + "?" + query;

也就是说,你已经在使用jQuery,所以你不应该首先手动构造URL:

var url = 'https://www.aviationweather.gov/adds/dataserver_current/httpparam?datasource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=1.25'
$.ajax({
    type: "GET",
    url: proxy,
    data: {'url': url},
    // etc