php跨域问题记录
记录跨域问题
一、问题
在控制层加了如下代码:
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN'] );
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: X-Requested-With,Content-Type,Accept');
打开chrome的network里的response,没有这几个值~
但是同样的代码我在本地另一个项目里是OK的,项目环境是Nginx做了层代理,实际用的是PHP当Apache模块的方式,就开始怀疑:
- 输出时框架限制了
- Nginx/Apache限制了header(ps:我们项目是用Nginx当了反向代理,PHP当Apache模块)
- 灵魂拷问:PHP输出时这些header是怎么返回的?
二、解决
1.框架
用xdebug跟了下,没看到框架里有任何限制不能更改header
2.web服务器
看到response每次返回的都一样,以为是运维控制了返回的选项,不能随意添加,和运维同事沟通了下,发现确实是不能随意添加header头,窃喜以为找到了原因。然而另一个同事说加的跨域允许是OK的;Nginx的conf里加的proxy 也是把Apache返回的header都返回了,排除
3.文件问题
重新思考,跨域问题是浏览器控制的,只要HTTP协议里返回的access允许就可以了。
使用header_list()方法打印了下发送的header列表,发现自己写的那几个没返回。
换种思路,把这几行加到其他文件,发现可以,然后对比俩文件有啥区别,最后最后的原因是<?php这个标识是从第2行开始写的,即在header方法之前有了输出。
三、补充
1.同源策略
参考:
浏览器安全的基石是"同源政策",如果非同源,共有3种行为受到限制
- cookie、LocalStorage和IndexDB(浏览器提供的本地数据库)无法读取
- dom无法获得(如iframe和window.open如果不同源,就无法通信)
- ajax请求不能发送
这里主要讨论下ajax的跨域解决方法,
2.跨域解决方式:
- jsonp
- cors
- 反向代理
2.1 jsonp
全称:json for padding 本质是用<script>标签可以跨域访问的性质,动态创建一个script,然后回调js数据脚本,请求类型是js而非xhr.普通接口返回的是数据对象,而jsonp是js数据脚本
2.2 CORS
CORS是一个W3c标准,全称是“跨域资源共享”(cross-origin resource sharing),允许浏览器向跨源服务器,发出XMLHttpRequest请求。
需要浏览器和服务器同时支持。目前所有浏览器都支持该功能,整个cors通信过程不需要用户参与。
浏览器将cors请求分为两种:简单请求和非简单请求
只要同时满足以下两个条件,就属于简单请求:
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
否则属于非简单请求。
2.2.1 简单请求
浏览器在头信息中增加一个origin字段,用来说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值决定是否同意这次请求。
如果服务器没有返回access这样的头部信息,即服务器没支持的话,前端的console里会显示access to xmlHttpRequest ...has been blocked by CORS policy...
如果origin指定的域名在许可范围内,服务器返回的响应会多出几个头信息字段:
Access-Control-Allow-Origin: xxxx
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: xxx
Access-Control-Allow-Origin:
是必须的,值要么是请求时origin字段的值,要么是*表示接受任意域名的请求。
Access-Control-Allow-Credentials
可选,布尔值,表示是否允许发送cookie,不同源时请求中不会带cookie,设为true表示服务器许可cookie可以包含在请求中,
XMLHttpRequest.withCredentials属性是一个boolean类型,表示是否该使用cookie,authorization header(头部授权)或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制请求。
参考:
xmlHttpRequest.withCredentials
Access-Control-Expose-Headers
可选,cors请求时,xmlHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
如果要带上cookie,后台的origin就不能设为*,且需要前端设置如下:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
2.2.2 非简单请求
是对服务器有特殊请求的:如请求方法是put或delete,或者content-type字段的类型是application/json.
非简单请求会在正式通信之前,增加HTTP查询请求,称为预检请求。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单中,以及可以使用那些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
预检请求
1)请求:
预检请求用的方法是option,表示这个请求时用来询问的。头信息里关键字段是origin表示请求来自哪个源。
2)回应:
服务器收到预检请求后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
服务器返回的Access-Control-Max-Age
该字段可选,用来指定本次预检请求的有效期,单位为秒。上面结果中,有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求
一旦服务器通过了预检请求,以后每次浏览器正常的cors请求都和简单请求一样。
php跨域问题记录的更多相关文章
- jsonp跨域问题记录
这段时间用H5做移动app开发,遇到不少之前做web的时候不曾遇到的问题,记录一下,共勉-- 首先说一个:js跨域取数的问题 描述: 之前做web都是通过后台获取数据,没考虑过跨域的问题.这次用h5 ...
- nginx跨域问题记录
现象:访问 toolbox.chinasoft.com 提示如下:Access to Font at 'https://images.chinasoft.com/static-toolbox/styl ...
- axios跨域问题记录
axios({headers: {'X-Requested-With': 'XMLHttpRequest','Content-Type': 'application/json; charset=UTF ...
- 还在问跨域?本文记录js跨域的多种实现实例
前言 众所周知,受浏览器同源策略的影响,产生了跨域问题,那么我们应该如何实现跨域呢?本文记录几种跨域的简单实现 前期准备 为了方便测试,我们启动两个服务,10086(就是在这篇博客自动生成的项目,请戳 ...
- webuploader 跨域上传demo(还没有写记录一下)
webuploader 跨域上传demo(还没有写记录一下)
- 2019-03-26 SpringBoot项目部署遇到跨域问题,记录一下解决历程
近期SpringBoot项目部署遇到跨域问题,记录一下解决历程. 要严格限制,允许哪些域名访问,在application.properties文件里添加配置,配置名可以自己起: cors.allowe ...
- 今天来记录一下关于ajax跨域的一些问题。以备不时之需。
今天来记录一下关于ajax跨域的一些问题.以备不时之需. 跨域 同源策略限制 同源策略阻止从一个域上加载的脚本获取或操作另一个域上的文档属性.也就是说,受到请求的 URL 的域必须与当前 Web 页面 ...
- 记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑
我通过这篇文章把今天工作中遇到的HTTP跨域和OPTION请求的一个坑记录下来. 场景是我需要在部署在域名a的Web应用里用JavaScript去消费一个部署在域名b的服务器上的服务.域名b上的服务也 ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
随机推荐
- Cookie Session和自定义分页
cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...
- java基础-01基本概念
java的特点 跨平台 所谓的平台,我们可以理解为操作系统. 大部分语言是不能跨平台的,比如c语言的程序在windows和linux上需要编写不同的代码. java程序是运行在JVM(Java Vir ...
- 【git】git hello world
以前不怎么会用. http://blog.sina.com.cn/s/blog_1485511700102xdig.html git add 文件夹/ 添加整个文件夹及内容 gi ...
- java.util.NoSuchElementException错误原因及解决方案
1.原因:没有控制语句导致的迭代器的越界,使得map中的数据无法传入reduce,从而无法把结果传入目标文件中. 在进行Mapreduce实例——WordCount实验时遇到的错误,开始以为是lib包 ...
- 总结idea几个实用的快捷键
Ctrl+R,替换文本Ctrl+F,查找文本 Ctrl+shit+R,全局替换文本Ctrl+shit+F,全局查找文本 Ctrl+Alt+L,格式化代码Alt+Insert,可以生成构造器/Gette ...
- 前端可视化项目流程,涉及three.js(webGL),3DMax技术,持续更新
最近在做一个可视化展示的项目,记录一下流程: 建模,模型来源,可以参考沙盘展示类项目,自己建模或者拼装其他源模型(本人以前是3D建模师,可以应付一些简单的场景) 有效模型导入到web端,这里采用的ob ...
- c提高第五次作业
重写结构体嵌套一级指针老师和二级指针学生的代码 //结构体类型,每个导师有三个学生 typedef struct Teacher { char *tName; //导师 char **stu; //三 ...
- pycharm failed to create JVM
启动的时候,出现这个error: 解决办法: 如果电脑安装的jdk是64位,找到pycharm的安装目录下的bin目录下的pycharm64.exe.vmoptions文件修改以下值, 如果是32位, ...
- rk3128 手动挂载 U 盘
2019-04-16 关键字: RK . 挂载.U盘 笔者手里有一块非常原生的运行 Android 4.4 操作系统的 RK3128 开发板.原生到各种功能模块都不能用的地步.今天就遇到一个不按常理出 ...
- 数据分析三剑客之Matplotlib
Matplotlib绘图和可视化 简介 我的前面两篇文章介绍了 Nimpy ,Pandas .今天来介绍一下Matplotlib. 简单来说,Matplotlib 是 Python 的一个绘图库.它包 ...