欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

深入了解跨领域问题

最编程 2024-07-09 08:28:35
...

前后端分离一时爽,跨域问题愁断肠,自从使用前后端分离进行WEB开发,跨域问题就一直是前后端联调遇到的第一个问题,今天我们来聊聊跨域问题和解决方案。

跨域问题

首先了解一下http请求当中的统一资源定位符(url),使用http协议访问,其实就是基于域名去访问服务器上的资源,既然是资源,那么自然有存放的地址,url就是提供给用户向服务器请求资源的资源地址,有点像你提供给外卖大哥的收货地址,URL的结构如下:

image.png

用户通过url访问服务器,服务器返回资源给用户,但是在这个过程当中会有很多安全问题,比如,CSRF(跨域攻击),XSS等。这些安全问题通常都需要用到服务器下发到浏览器本地的内容,比如cookie比如localstorage,那么,这种情况下浏览器为了保证安全,就提出了同源策略:同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。非同源本身也可以访问,但是如果使用浏览器,浏览器会进行请求拦截,这就是好多小伙伴聊到的,我用postman,curl,脚本都可以访问,为啥使用浏览器就不可以了,一般会返回 403 forbidden。同源策略提高了前端访问的安全性,同样也带来了一些问题,这些由于同源策略导致的问题就是跨域问题,跨域问题通常会导致:

1、Cookie、LocalStorage、IndexedDB 限制

2、DOM节点限制

3、ajax请求限制

当然对静态文件加载是没有跨域的,比如:图片,css, js或者a标签。

解决方案

解决跨域问题的思路通常有下面三种:

1、使用跨域不限制的方法请求

这个思路当中最典型的就是jsonp,利用

基本的代码如下:

前端:

<script type='text/javascript'>
    window.jsonpCallback = function (res) {
        console.log(res)
    }
</script>
<script src='http://127.0.0.1:8000/user?id=1&callback=jsonpCallback' type='text/javascript'></script>

后端(Python Flask)

import json
from flask import Flask
from flask import request
​
app = Flask(__name__)
​
users = {
    "1": {"name": "张三", "age": 18}
}
​
@app.route("/user")
def userFun():
    id = request.args.get("id")
    callback = request.args.get('callback')
    
    user_data = json.dumps(users.get(id))
    
    result = callback+"("+user_data+")" #这里返回的user_data就会作为jsonp回调函数接受的数据    
    return result
​
if __name__ == "__main__":
    app.run(port = 8000)

当然,cors,postMessage,websocket也可以实现跨越的效果。

2、在服务端允许跨域访问

这个逻辑就是在响应数据的时候,设置响应头,通过响应头来保证响应可以跨越,这里还是以flask来举例子。

import json
from flask import Flask
from flask import request
​
app = Flask(__name__)
​
#....@app.after_request
def corsFun(response):
    response.headers['Access-Control-Allow-Origin'] = '*'
    response.setHeader("Access-Control-Allow-Headers", "*")
    response.setHeader("Access-Control-Allow-Methods", "*")
    response.setHeader("Access-Control-Allow-Credentials", "true")
    return response
​
if __name__ == "__main__":
    app.run(port=8000)

3、转跨域请求为同源请求

个人感觉,这种方法在开发过程最实惠,就是得提前做好规划,然后和运维的小伙伴打好基础,最简单的实现,nginx转发为同源,基本的配置:

server {
    listen 80;
    
    location / {
        root /usr/share/nginx/html;
        index  index.html index.htm; //后端接口地址
    }
​
    //转发接口地址
    location /api {
        proxy_path 127.0.0.1:8000/api; //后端接口地址
    }
}

那么前端就可以通过请求 http://nginx_host:80/api请求到后端服务

关于跨域和同源就先聊这么多,具体使用哪种还是要结合实际的使用场景的。

推荐阅读