zoukankan      html  css  js  c++  java
  • 用 PHP 编写跨域访问代理

    由于安全上的限制,在浏览器中使用 JavaScript 不能直接访问跨域的资源。我们可以通过服务器来中转:用 PHP 编写一个简单地跨域访问代理。

    一般需要支持 GET 和 POST 这两种 HTTP 请求。对于 GET 方式,我们可以用 fopen,file_get_contents 和 curl 来抓取资源。在网上查询得知 curl 速度会快一些,而且会缓存 DNS 信息,所以就使用 curl 来处理。例子如下:

    function curlget($url) {
      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_HEADER, false);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      $data = curl_exec($ch);
      if ($data === false) {
        header('HTTP/1.1 400 Bad Request');
        exit;
      } else {
      echo $data;
    }
    

    我们也可以用 curl 来处理 POST 请求。我们至少需要区分两种 POST 请求:第一种的 Content-Type 为 application/x-www-form-urlencoded,仅仅用于提交参数;而第二种的 Content-Type 为 multipart/form-data,用于上传文件。POST 请求的例子如下:

    function curlpost($url, $data) {
      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_HEADER, false);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($ch, CURLOPT_POST, true);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
      $data = curl_exec($ch);
      if ($data === false) {
        header('HTTP/1.1 400 Bad Request');
        exit;
      } else {
      echo $data;
    }
    

    其中 curl_setopt 的 CURLOPT_POSTFIELDS 选项中,如果 $data 是字符串,curl 提交时将设置 Content-Type 为 application/x-www-form-urlencoded;如果 $data 是包含 'file' 项的数组,curl 提交时将设置 Content-Type 为 multipart/form-data。

    现在我们假定:客服端将要访问的地址作为 URL 的 path 参数发送过来,即 JavaScript 代码类似于下面:

    var path = 'http://some.domain.com/some/page/';
    var url = 'http://example.com/?path=' + encodeURIComponent(url);
    

    在 PHP 中,不管是 GET 方式还是 POST 方式的请求,URL 中的参数(即上面的 path 值)都放在 $_GET 数组中。而 POST 方式提交的数据,如果是 application/x-www-form-urlencoded 的请求,放在 $_POST 数组中;如果是 multipart/form-data 的请求,所上传的文件存放在临时目录中,文件的基本信息放在 $_FILES 数组中。理解了这些知识后,我们可以用下面的代码来处理请求:

    var $url = $_GET['path'];
    
    switch ($_SERVER['REQUEST_METHOD']) {
        case "GET":
            curlget($url);
            break;
        case "POST":
            switch($_SERVER['CONTENT_TYPE']) {
                case 'application/x-www-form-urlencoded':
                    $data = http_build_request($_POST);
                    break;
                case 'multipart/form-data':
                    $tempname = $_FILES['file']['tmp_name'];
                    $basename = basename($_FILES['file']['name']);
                    $origname = sys_get_temp_dir() . '/' . $basename;
                    move_uploaded_file($tempname, $origname);
                    chdir(sys_get_temp_dir());
                    $data = array('name' => 'file', 'filename' => '@' . $basename);
                    break;
                default:
                    exit;
            }
            curlpost($url, $data);
            break;
        default:
            exit;
    }

    其中使用 chdir 函数是为了保证 curl 提交文件时不包含路径。

    参考资料:
    [1] JavaScript: Use a Web Proxy for Cross-Domain XMLHttpRequest Calls
    [2] PHP 手册:file_get_contents
    [3] PHP 手册:cURL 函数
    [4] file_get_contents VS CURL, what has better performance?
    [5] 简评file_get_contents与curl 效率及稳定性
    [6] PHP 手册:$_GET
    [7] PHP 手册:$_POST
    [8] PHP 手册:$_FILES
    [9] PHP 手册:$_SERVER
    [A] PHP 手册:http_build_query
    [B] PHP 手册:move_uploaded_file
    [C] HTML 4.01 Specification - Forms
    [D] Get “Content-Type” header of request in PHP
    [E] Form Data Processing
    [F] PHP 文件上传
    [G] arkadi / phpproxy / source - Bitbucket
    [H] CORS Proxy
    [I] node.js based CORS proxy

  • 相关阅读:
    文档视图
    引入缓冲池技术
    数据库访问与查询
    OnInitialUpdate函数
    显示股票视图的全局函数
    切换视图的核心代码
    GuiEdit的使用
    操作方法
    SQL 使用 解析
    调用API 实现 窗体 拖动
  • 原文地址:https://www.cnblogs.com/zoho/p/2575380.html
Copyright © 2011-2022 走看看