当前位置:首页 > PHP教程 > php高级应用 > 列表

php解决跨域问题的方法详解

发布:smiling 来源: PHP粉丝网  添加日期:2024-09-26 20:42:26 浏览: 评论:0 

跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域,这篇文章主要为大家详细介绍了php解决跨域问题的相关方法,需要的可以参考下。

跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域。

比如,在实际项目中由于前后端分离当前端需要通过接口向后台发起请求,此时就会出现跨域问题,那么,这类问题需要如何解决呢?

其实php解决跨域问题很简单,只需加上下面的代码就可以了:

header("Access-Control-Allow-Origin:*");

加上这行代码表示允许所有的域名访问,不过为了安全起见,在实际项目中往往会限定只允许固定的几个域名和方法发起的请求。

1、允许单个域名访问

header('Access-Control-Allow-Origin:http://www.startphp.cn');

header('Access-Control-Allow-Methods:POST');    //表示只允许POST请求

header('Access-Control-Allow-Headers:x-requested-with, content-type'); //请求头的限制

2、不限制域名

header('Access-Control-Allow-Origin:*');

header('Access-Control-Allow-Methods:POST');//表示只允许POST请求

header('Access-Control-Allow-Headers:x-requested-with, content-type');

3、允许多个域名访问

在实际项目中最好指定能跨域访问的域名,增加安全性。可以写在一个公共类里面,封装一个方法调用。

  1. // 设置能访问的域名 
  2.  
  3. static public $originarr = [ 
  4.  
  5.    'https://test1.com'
  6.  
  7.    'https://test2.com'
  8.  
  9. ]; 
  10.  
  11.   
  12.  
  13. /** 
  14.  
  15.  *  公共方法调用 
  16.  
  17.  */ 
  18.  
  19. static public function setheader() 
  20.  
  21.  
  22.    // 获取当前跨域域名 
  23.  
  24.    $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''
  25.  
  26.    if (in_array($origin, self::$originarr)) { 
  27.  
  28.       // 允许 $originarr 数组内的 域名跨域访问 
  29.  
  30.       header('Access-Control-Allow-Origin:' . $origin); 
  31.  
  32.       // 响应类型 
  33.  
  34.       header('Access-Control-Allow-Methods:POST,GET'); 
  35.  
  36.       // 带 cookie 的跨域访问 
  37.  
  38.       header('Access-Control-Allow-Credentials: true'); 
  39.  
  40.       // 响应头设置 
  41.  
  42.       header('Access-Control-Allow-Headers:x-requested-with,Content-Type,X-CSRF-Token'); 
  43.  
  44.    } 
  45.  

在php上如何实现

  1. <?php
  2.  
  3. // 制定允许其他域名访问 
  4.  
  5. header("Access-Control-Allow-Origin:*"); 
  6.  
  7. // 响应类型 
  8.  
  9. header('Access-Control-Allow-Methods:POST'); 
  10.  
  11. // 响应头设置 
  12.  
  13. header('Access-Control-Allow-Headers:x-requested-with, content-type'); 
  14.  
  15. //$callback = isset($_REQUEST['callback']) ? trim($_REQUEST['callback']) : ''; //jsonp回调参数,必需  
  16.  
  17. function getKey($key,$default=""){ 
  18.  
  19.     return trim(isset($_REQUEST[$key])?$_REQUEST[$key]:$default); 
  20.  
  21.   
  22.  
  23.  
  24. $id = getKey("id"); 
  25.  
  26. $conn = mysqli_connect("localhost","root","","test"or die("连接失败"); 
  27.  
  28. $conn->query("set names utf8"); 
  29.  
  30. $sql = "select * from data where ".$id." is not null" 
  31. $result = $conn->query($sql); 
  32.  
  33. $arr = []; 
  34.  
  35. while($row=$result->fetch_assoc()){ 
  36.  
  37.     array_push($arr,json_encode($row));  
  38.  
  39. $json = json_encode($arr);  //json 数据 
  40.  
  41. print_r($json); 

4 Nginx反向代理

使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。

实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

修改配置文件nginx.conf,如下:

  1. // proxy服务器 
  2.  
  3. server { 
  4.  
  5.     listen       81; 
  6.  
  7.     server_name  www.domain1.com; 
  8.  
  9.     location / { 
  10.  
  11.         proxy_pass   http://www.domain2.com:8080;  #反向代理 
  12.  
  13.         proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名 
  14.  
  15.         index  index.html index.htm; 
  16.  
  17.   
  18.  
  19.         # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用 
  20.  
  21.         add_header Access-Control-Allow-Origin http://www.domain1.com;  #当前端只跨域不带cookie时,可为* 
  22.  
  23.         add_header Access-Control-Allow-Credentials true; 
  24.  
  25.     } 
  26.  

配置修改好后,再重启nginx。

index.html文件访问代理服务器

  1. // index.html 
  2.  
  3. var xhr = new XMLHttpRequest(); 
  4.  
  5. // 前端开关:浏览器是否读写cookie 
  6.  
  7. xhr.withCredentials = true
  8.  
  9. // 访问nginx中的代理服务器 
  10.  
  11. xhr.open('get', 'http://www.domain1.com:81/?user=admin', true); 
  12.  
  13. xhr.send(); 

server.js

  1. // server.js 
  2.  
  3. var http = require('http'); 
  4.  
  5. var server = http.createServer(); 
  6.  
  7. var qs = require('querystring'); 
  8.  
  9. server.on('request'function(req, res) { 
  10.  
  11.     var params = qs.parse(req.url.substring(2)); 
  12.  
  13.     // 向前台写cookie 
  14.  
  15.     res.writeHead(200, { 
  16.  
  17.         'Set-Cookie''l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'   // HttpOnly:脚本无法读取 
  18.  
  19.     }); 
  20.  
  21.     res.write(JSON.stringify(params)); 
  22.  
  23.     res.end(); 
  24.  
  25. }); 
  26.  
  27. server.listen('8080'); 
  28.  
  29. console.log('Server is running at port 8080...');

Tags: php跨域问题如何解决 php如何解决跨域问题

分享到: