这里记录一下跨域问题处理的过程。
实际场景
需求主要是一个话题互动页面,在评论框中需满足能够上传图片的要求,需求看似平平常常,处理起来也没什么太大的问题,那就开干吧。
页面依赖的插件zepto.js
plupload.js
实际场景的代码片段
1 | // 评论框中的 dom 结构 |
1 | // 初始化 plupload 上传图片插件事件 |
运行代码,结果报错。为什么上传图片到服务器不成功?
报错如下:
很明显,这是跨域的报错。
一个域名地址的组成:
http:// | www. | xxx.com | :8080 | files/filsname |
---|---|---|---|---|
协议 | 子域名 | 主域名 | 端口号 | 请求资源地址 |
当协议、子域名、主域名、端口号中任一不相同时都不能算做同域,在不同域之间互相请求资源时就算作‘跨域’
常见跨域处理
1.常见的 jsonp 跨域
虽然在页面上调用不同域的接口不被允许,但是调用不同域的资源(如js脚本)是被允许的,jsonp 则正是利用这个特性来进行跨域数据请求处理。
比如在 a.html
页面上,它里面的代码需要利用 ajax 获取不同域上的 json 数据,假设数据地址是 http://b.com/data.php
那么 a.html
中的代码可以这样:
1 | <script> |
因为后端代码是当做一个js文件来引入的,则它必须返回的是一个能执行的js文件,即后端代码如下:
1 | <php? |
最终页面上会输出doSomething([‘a’,’b’,’c’])
,即这样我们就可以通过jsonp获取跨域的请求数据了。
2.XHR2(html5)处理跨域方式
html5提供的XMLHttpRequest Level2已经实现了跨域访问以及其他的一些新功能,这个功能就很方便,在所有的现代浏览器中基本上已经全部支持,如果是开发 h5 页面的话基本上不用考虑支持的问题
在使用的时候客户端不用做任何事情,只需要服务端修改支持跨域的几个请求头即可:
1 | 'Access-Control-Allow-Origin':'*' |
这些请求头设置可以根据自己的需要按需设置。
因为兼容性要求不高,自己直接采用了最新的XHR2跨域的处理方式,后端修改支持即可
但是由于奇葩的测试环境和线上环境,这里的跨域在当前梳理的时候一直不能成功,检查:
后端添加允许跨域已完成:
1 | 'Access-Control-Allow-Origin':'特定的网站地址' |
正常情况,前端此时不需要做其他设置是能够成功发送请求的,但是这里就是不讲道理
和后端沟通后得知,请求已经成功,但是他们的验证用户是否登录是直接校验的请求带回的 cookie 中是否有用户标识
查看请求如下
cookie情况如下
从图中可见, cookie 存在,而 cookie 本来在请求是是会自动将值带上的,但是在域不同的时候肯定是不会自动将值加入
那么这里就是这个原因造成的,但是在js代码中处理了一波 cookie 的 domain 是允许跨域的地址后再次发起请求
问题依旧存在,请求如图:
option 请求简单理解:例如在接口发起post请求处于跨域情况下,首先会自动发送一个option请求到服务器进行确认
如果成功,就再发起一次本来是post请求到服务器且服务器返回成功信息
若服务器不允许,那么这里就拜拜咯,下面的操作仍然不能继续
这里有一个需要注意的点,这个时候前端是无能为力的,需要后端将option请求的操作进行一个处理,让此操作也能成功跨域,并且上图中的 origin 一定注意,也要设置成允许跨域的地址(允许所有就是*,特定某个地址就设置成具体的某个地址)
经过前后端共同努力,问题最终得到了解决。
- 本文作者: Jambo
- 版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!