跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域。
比如,在实际项目中由于前后端分离当前端需要通过接口向后台发起请求,此时就会出现跨域问题,那么,这类问题需要如何解决呢?
其实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、允许多个域名访问
在实际项目中最好指定能跨域访问的域名,增加安全性。可以写在一个公共类里面,封装一个方法调用。
// 设置能访问的域名
static public $originarr = [
'https://test1.com',
'https://test2.com',
];
/**
* 公共方法调用
*/
static public function setheader()
{
// 获取当前跨域域名
$origin = isset($_server['http_origin']) ? $_server['http_origin'] : '';
if (in_array($origin, self::$originarr)) {
// 允许 $originarr 数组内的 域名跨域访问
header('access-control-allow-origin:' . $origin);
// 响应类型
header('access-control-allow-methods:post,get');
// 带 cookie 的跨域访问
header('access-control-allow-credentials: true');
// 响应头设置
header('access-control-allow-headers:x-requested-with,content-type,x-csrf-token');
}
}在php上如何实现
<?php
// 制定允许其他域名访问
header("access-control-allow-origin:*");
// 响应类型
header('access-control-allow-methods:post');
// 响应头设置
header('access-control-allow-headers:x-requested-with, content-type');
//$callback = isset($_request['callback']) ? trim($_request['callback']) : ''; //jsonp回调参数,必需
function getkey($key,$default=""){
return trim(isset($_request[$key])?$_request[$key]:$default);
}
$id = getkey("id");
$conn = mysqli_connect("localhost","root","","test") or die("连接失败");
$conn->query("set names utf8");
$sql = "select * from data where ".$id." is not null";
$result = $conn->query($sql);
$arr = [];
while($row=$result->fetch_assoc()){
array_push($arr,json_encode($row));
}
$json = json_encode($arr); //json 数据
print_r($json);4 nginx反向代理
使用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持session,不需要修改任何代码,并且不会影响服务器性能。
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。
修改配置文件nginx.conf,如下:
// proxy服务器
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header access-control-allow-origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header access-control-allow-credentials true;
}
}
配置修改好后,再重启nginx。
index.html文件访问代理服务器
// index.html
var xhr = new xmlhttprequest();
// 前端开关:浏览器是否读写cookie
xhr.withcredentials = true;
// 访问nginx中的代理服务器
xhr.open('get', 'http://www.domain1.com:81/?user=admin', true);
xhr.send();
server.js
// server.js
var http = require('http');
var server = http.createserver();
var qs = require('querystring');
server.on('request', function(req, res) {
var params = qs.parse(req.url.substring(2));
// 向前台写cookie
res.writehead(200, {
'set-cookie': 'l=a123456;path=/;domain=www.domain2.com;httponly' // httponly:脚本无法读取
});
res.write(json.stringify(params));
res.end();
});
server.listen('8080');
console.log('server is running at port 8080...');以上就是php解决跨域问题的方法详解的详细内容,更多关于php解决跨域的资料请关注代码网其它相关文章!
发表评论