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

标签 php jquery ajax proxy

在过去的几天里,我一直在为这个问题烦恼。我正在尝试从公共(public) 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

jQuery:

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

关于php - 使用 php 代理的跨域 Ajax GET 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35862855/

相关文章:

ios - CDVURLProtocol - 触发 ajax 调用时未执行 startLoading 方法

php - 如何获取foreach中的迭代总数

PHP 从 MySQL 表获取父信息

JQuery简单选项卡程序不显示嵌套的Div标签

javascript - 如何在第一次点击后禁用链接并允许用户仅在登录后投票

jquery - 如何在 .getJSON jQuery 中设置编码

php - 如何在 tymondesigns/jwt-auth 包生成的 laravel 5 中捕获全局异常?

javascript - 如何通过类名和存储获取页面中的所有链接

javascript - 只有当它有标题时才显示 img?

jquery - 即使未设置,qTip 也会显示边距?