最近测试一些东西,需要跨域访问Restful接口,因为是测试,不可能改变接口形式,所以jsonp方案直接Pass。
本地测试时简单写了几行NodeJS代码,对特定路径下的请求进行转发后回传,因为使用WebStorm开发,NodeJS不可以和WebStorm内置服务器使用相同端口,虽然可以通过配置本地服务器,完全将NodeJS作为服务器,但那样需要解决静态资源的输出,写东西过多,偏离初衷,这里不再赘述。
不过如果你是做前后端完全分离的项目,大可以找个开源的Web框架来用,比如express等,这里不多介绍。
总之但思路就这样了,可能不太完善,代码如下:
/** * Created by William.Wei on 2016/4/23. */ var http = require('http'); var server = http.createServer(); server.on('request', function (request, response) { console.log(request.url); response.setHeader('Access-Control-Allow-Origin','*'); response.setHeader('Content-type', 'text/html;charset=UTF-8'); http.request({ hostname: 'www.poorren.com', port: 80, path: request.url, method: request.method }, function (res) { res.on('data', function (data) { response.write(data); }); res.on('end', function () { response.end(); }); }).end(); }); server.listen(88);
如上,因为是不同端口,所以本质上采用的CORS,所以仅仅是中转思路而已,通过Web端ajax入口url统一处理后访问端口为88的地址即可。
本地没问题了,想放到外网玩呢?如果有托管主机或者VPS啥的还好,个人是不喜欢折腾,平时测些简单的页面啥的,直接丢虚拟主机,因为目前可以跑NodeJS的虚拟主机寥寥无几,就想到了PHP,刚好公司有人封装有Restful请求工具,参考源代码简化处理了一下,最终代码如下:
<?php class Rest { private $baseURL; private $http_headers = []; private $curl_opts; private $method; private $params = []; private $urlParam = ""; private $httpHeader = []; private $acceptXmlType = "Accept:application/xml"; private $acceptJsonType = "Accept:application/json"; public function __construct($method, $baseURL = '') { $this->baseURL = $baseURL; $this->method = $method; $this->curl_opts = array( CURLOPT_CONNECTTIMEOUT => 60, /* 在发起连接前等待的时间,如果设置0,则无限等待 */ CURLOPT_TIMEOUT => 300, /* 允许执行的最长秒 */ CURLOPT_USERAGENT => 'poorren.com', CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false, CURLOPT_FOLLOWLOCATION => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false ); } private function getUrlParams() { return $this->urlParam; } private function getSetting() { if ($this->method == "POST") { // post数据 $this->curl_opts[CURLOPT_POST] = true; if (is_string($this->params)) { $this->curl_opts[CURLOPT_POSTFIELDS] = $this->params; } else { $this->curl_opts[CURLOPT_POSTFIELDS] = json_encode($this->params, JSON_UNESCAPED_UNICODE); } } else if ($this->method == "PUT") { // put数据 $fields = is_array($this->params) ? http_build_query($this->params) : $this->params; $this->curl_opts[CURLOPT_CUSTOMREQUEST] = 'PUT'; $this->curl_opts[CURLOPT_RETURNTRANSFER] = true; $this->curl_opts[CURLOPT_POSTFIELDS] = $fields; } else { $urlParam = ""; if ($this->params != null) { foreach ($this->params as $key => $value) { $urlParam = $urlParam . "$key=" . urlencode($value) . "&"; } } $this->urlParam = $urlParam; } $this->curl_opts[CURLOPT_HTTPHEADER] = $this->httpHeader; return $this->curl_opts; } private function execute($resource) { $ch = curl_init(); curl_setopt_array($ch, $this->getSetting()); if (!empty($this->http_headers)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $this->http_headers); } $urlParams = $this->getUrlParams(); if (strpos($this->baseURL . $resource, '?') > 0) { $requestUrl = $this->baseURL . $resource . "&" . $urlParams; } else { $requestUrl = $this->baseURL . $resource . "?" . $urlParams; } curl_setopt($ch, CURLOPT_URL, $requestUrl); $result = curl_exec($ch); $code = curl_errno($ch); if ($code != 0) { $msg = curl_error($ch) . " request url is ({$code}):" . $requestUrl; throw new Exception($msg, $code); } $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code != 200) { throw new Exception($requestUrl); } return $result; } public function invoke($path, $params, $jsonParse = true, $acceptType = 'json') { $this->params = $params; if ($acceptType == 'xml') { $this->httpHeader[0] = $this->acceptXmlType; } else { $this->httpHeader[0] = $this->acceptJsonType; } $content = $this->execute($path); return $jsonParse ? json_decode($content) : $content; } public function setHeaders($headers) { if (empty($headers)) { return; } foreach ($headers as $k => $v) { $this->http_headers[$k] = $v; } } }
仔细看的同学可能发现了,这个貌似和上次发的图片代理《两行代码绕过基于referrer的防盗链》有类似作用,感兴趣的同学可以以此为基础来改造一下,就是个全功能图片代理。
以上为开发、测试用代码,仅分享,不建议使用到生产环境。
上一篇: 两行代码绕过基于referrer的防盗链 下一篇: QQ内置浏览器下网页行高、字体大小显示异常解决