导读:本篇文章首席CTO笔记来给大家介绍有关django跨域请求如何解决的相关内容,希望对大家有所帮助,一起来看看吧。
请求接口时跨域问题,前端解决方法
在前后端接口请求中,由于浏览器的限制,会出现跨域的情况。常用的跨域方案有:
1、JSONP跨域
2、Nginx反向代理
3、服务器端修改header
4、document.domain
5、window.name
6、postMessage
7、后台配置运行跨域
当一个请求url的 协议、域名、端口 三者之间任意一个与当前页面url不同即为跨域
特别注意两点:
1、如果是协议和端口造成的跨域问题“前台”是无能为力的,
2、在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
记一次uwsgi导致的跨域问题
后台是NGINX+uwsgi+Django,配置了公司内网域名,但是每经过一段时间使用,便会出现接口报错,排查下来发现是接口跨域导致的报错
初期排查过程中已经确认过Django中已经配置了跨域,且是使用一段时间后才出现跨域,后发现当提示跨域错误时清理cookie会解决问题,遂逐一删除cookie内的测试是否因为某条cookie导致的跨域,最后发现是因为一条键值名为user的cookie导致的跨域,发现user对应的cookie长度为283,更改user值的长度也可以解决跨域问题,最终定位问题原因是因为cookie过长导致的跨域。
找到原因是cookie过长导致,剩下就是排查具体哪里配置导致的问题,首先查看服务接口调用日志发现浏览器报错情况下服务没有接口调用日志,中间排查过程中忽略了uwsgi的配置,导致一直在nginx相关配置中查找问题,一开始以为是nginx的buffer大小的设置问题,后来发现更改后问题依然存在,最终想到uwsgi的配置,最后发现是uwsgi的buffer-size默认是4k,最终调整为32k解决问题。
跨域以及解决跨域的几种方式
跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能 同源 使用的限制。
同源策略 是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议 + 域名 + 端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
常见的跨域场景:
对于简单请求,浏览器会直接发出CORS请求,具体的就是在头信息中,增加一个 Origin 字段。
非简单请求是那种对服务器有特殊要求的请求,譬如 put delete 方法,或者 Content-Type 字段类型是 application/json 的,非简单请求在正式通信前,会增加一次请求,称为预检请求,也就是 options 方法。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。
与简单请求不同的是, option 请求多了2个字段:
Access-Control-Request-Method :必须字段,用来列出浏览器的CORS请求会用到哪些HTTP方法。
Access-Control-Request-Headers :该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段。
服务器收到"预检"请求以后,检查了 Origin 、 Access-Control-Request-Method 和 Access-Control-Request-Headers 字段以后,确认允许跨源请求,就可以做出回应。
表明服务器支持的所有跨域请求的方法。
表明服务器支持的所有头信息字段,不限于浏览器在"预检"中请求的字段。
表示是否允许发送认证信息(Cookie)。
指定本次预检请求的有效期,单位为秒,允许缓存。在缓存期间,不用发出另一条预检请求。
什么是跨域、怎么解决跨域?
一个请求url的** 协议、端口、域名 **其中任意一个与当前页面url不相同就是跨域
即: (http/https)协议、(segmentfault)主域名、(www)子域名、(8080)端口
是因为浏览器的同源策略的限制,同源策略是一种安全策略,同源指的是域名,协议,端口相同,会阻止一个域的js脚本和另一个域的内容进行交互。防止在一个浏览器中的两个页面产生不安全、异常的行为。
当然如果不同源的话会产生一定的限制:
【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
【2】无法接触非同源网页的 DOM
【3】无法向非同源地址发送 AJAX 请求
document.createElement(‘script’) 生成一个 script 标签,然后插 body 里而已。
JSONP的实现原理就是创建一个script标签, 再把需要请求的api地址放到src里. 这个请求只能用GET方法, 不可能是POST(向服务端传送数据)。
一种非正式传输协议,它会允许用户传递一个callback参数给服务端,然后服务端返回数据的时候会将这个callback参数作为函数名来包裹住JSON数据,然后客户端就可以随意的定义自己的函数来处理返回的数据了。
一般是后端在处理请求数据的时候,添加允许跨域的请求头信息,服务端设置Access-Control-Allow-Origin就可以,如果需要携带cookie,前后端都需要设置
window对象有个name的属性,在一个window下,窗口载入的页面都是共享一个window.name。
在a.html中,怎么把b.html页面加载进来,获取b.html的数据。在a.html页面使用iframe,可以去获取b.html的数据,然后在a.html页面中取得iframe获取得数据。
但是iframe想要获取b.html中的数据,只需要给这个iframe的src设为就可以,如果a.html想要得到iframe所获得的数据,也就是iframe的window.name的值,还要把这个iframe的src设成跟a.html页面同一个域才可以,不然a.html访问不到iframe里的window.name属性。
// 父窗口打开一个子窗口
var openWindow = window.open('', 'title');
// 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
openWindow.postMessage('Nice to meet you!', '');
调用message事件,监听对方发送的消息
// 监听 message 消息
window.addEventListener('message', function (e) {
console.log(e.source); // e.source 发送消息的窗口
console.log(e.origin); // e.origin 消息发向的网址
console.log(e.data); // e.data 发送的消息
},false);
server{
# 监听9099端口
listen 9099;
# 域名是localhost
server_name localhost;
#凡是localhost:9099/api这个样子的,都转发到真正的服务端地址
location ^~ /api {
proxy_pass ;
}
}
// 请求的时候直接用回前端这边的域名,这就不会跨域,然后Nginx监听到凡是localhost:9099/api这个样子的,都转发到真正的服务端地址
fetch('', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
msg: 'helloIframePost'
})
})
解决携带身份信息的跨域请求
![Y$EL]}B8CA)OU{)L 6F3WFD.png
axios 中这样设置
当前端配置修改后请求跨域就会出现第一步的错误,这时候就需要在服务器端设置了。
(顺带一说,感谢我的后端小伙伴成少在这个寂寞的夜晚陪我搞到深夜)
现在的情况是只有前端同意跨域请求携带cookie了,而后端还没有同意。所以在后台配置中也设置一下就好了。
django中setting.py的配置
[图片上传失败...(image-90d7c0-1556455798141)]
django+vue无法设置跨域cookies
后端开发环境:Django 3.2.9
前端开发环境:vue3 + ts
浏览器版本:chrome(96.0.4664.45)
问题:
最近开发一个新项目,前端使用axios进行http类的封装,前后端分离进行api调试,进行登录后,后续的api调用发现无法识别到cookie。
尝试情况:
1、axios设置withCredentials,无效
2、分析api请求和响应信息,发现响应标头有一段警告信息
3、联想到既然是响应标头出现报警信息,那么可以考虑从django入手。在官网上输入"SAMESITE",果然找到了相关的说明,通过在settings.py设置 SESSION_COOKIE_SAMESITE='None' 和 SESSION_COOKIE_SECURE=True 后成功解决问题。
结语:以上就是首席CTO笔记为大家整理的关于django跨域请求如何解决的相关内容解答汇总了,希望对您有所帮助!如果解决了您的问题欢迎分享给更多关注此问题的朋友喔~