浅谈为什么要限制跨域以及如何实现跨域

一、什么是跨域

当协议、子域名、主域名、端口号中任意一个不相同时,都算作不同域。不同域之间相互请求资源,就算作“跨域”。

二、为什么要限制跨域

浏览器的同源策略主要可以分为DOM同源策略和XMLHttpRequest同源策略。

DOM同源策略:

意为不同域之间的iframe之间可以互相访问,那么黑客就可以做一个假网页,在里面嵌套一个iframe(某银行网页),再把宽高拉满,此时如果用户输入账号密码,没有DOM同源策略的话则主网站可以跨域访问到iframe的节点,获取到用户的账号密码。

XMLHttpRequest 同源策略:

如果没有 XMLHttpRequest 同源策略,那么黑客可以进行 CSRF(跨站请求伪造) 攻击。

  1. 用户登录了自己的银行页面 http://mybank.com,http://mybank.com 向用户的 cookie 中添加用户标识。
  2. 用户浏览了恶意页面 http://evil.com,执行了页面中的恶意 AJAX 请求代码。
  3. http://evil.com 向 http://mybank.com 发起 AJAX HTTP 请求,请求会默认把 http://mybank.com 对应 cookie 也同时发送过去。
  4. 银行页面从发送的 cookie 中提取用户标识,验证用户无误,response 中返回请求数据。此时数据就泄露了。
  5. 而且由于 Ajax 在后台执行,用户无法感知这一过程。

三、跨域方式

1、CORS

CORS通信过程由后端服务器设置,并且默认不包含cookie及HTTP认证信息,如果要包含cookie,则需要:

  • 服务器指定了 Access-Control-Allow-Credentials: true
  • 开发者须在请求中打开withCredentials属性: xhr.withCredentials = true
  • Access-Control-Allow-Origin不要设为星号,指定明确的与请求网页一致的域名,这样就不会把其他域名的Cookie上传

简单请求:

同时满足以下两个条件,就是简单请求

  1. 请求方法是:HEAD、GET、POST,三者之一
  2. 请求头信息不超过以下几个字段:
    1. Accept
    2. Accept-Language
    3. Content-Language
    4. Last-Event-Id
    5. Content-Type:值为三者之一application/x-www/form/urlencoded、multipart/form-data、text/plain

服务器在发送请求时在头信息中加入Origin字段,表示请求来源来自哪个域(协议+域名+端口),服务器根据这个值决定是否同意请求。如果同意,返回的响应会多出以下响应头信息:

Access-Control-Allow-Origin: http://juejin.com // 和 Orign 一致  这个字段是必须的
Access-Control-Allow-Credentials: true // 表示是否允许发送 Cookie  这个字段是可选的
Access-Control-Expose-Headers: FooBar // 指定返回其他字段的值   这个字段是可选的
Content-Type: text/html; charset=utf-8 // 表示文档类型

非简单请求

比如 PUT 或 DELETE 请求,或 Content-Type 为 application/json ,就是非简单请求。

非简单 CORS 请求,正式请求前会发一次 OPTIONS 类型的查询请求,称为预检请求,询问服务器是否支持网页所在域名的请求,以及可以使用哪些头信息字段。只有收到肯定的答复,才会发起正式XMLHttpRequest请求,否则报错。 

2、Nginx代理跨域

配置一个代理服务器向服务器请求,再将数据返回给客户端,实质和CORS跨域原理一样,需要配置请求响应头Access-Control-Allow-Origin等字段

3、Node中间件代理跨域

Vue项目一般使用此方法,在vue.config.js文件中配置:

module.export = {
    ...
    devServer: {
        proxy: {
            [ process.env.VUE_APP_BASE_API ]: {
                target: \'http://xxxx\',//代理跨域目标接口
                ws: true,
                changeOrigin: true,
                pathRewrite: {
                    [ \'^\' + process.env.VUE_APP_BASE_API ] : \'\'
                }
            }
        }
    }
}

Node/Express中配置:

const express = require(\'express\')
const proxy = require(\'http-proxy-middleware\')
const app = express()
app.use(\'/\', proxy({ 
    // 代理跨域目标接口 
    target: \'http://xxxx:8080\', 
    changeOrigin: true, 
    // 修改响应头信息,实现跨域并允许带cookie 
    onProxyRes: function(proxyRes, req, res) { 
        res.header(\'Access-Control-Allow-Origin\', \'http://xxxx\')
        res.header(\'Access-Control-Allow-Credentials\', \'true\')
    }, 
    // 修改响应信息中的cookie域名 
    cookieDomainRewrite: \'www.domain1.com\' // 可以为false,表示不修改
})); 
app.listen(3000); 

4、Websocket

WebSocket是HTML5标准中的一种通信协议,以ws://(非加密)和wss://(加密)作为协议前缀,该协议不实行同源政策,只要服务器支持就行。

因为WebSocket请求头信息中有Origin字段,表示请求源来自哪个域,服务器可以根据这个字段判断是否允许本次通信,如果在白名单内,就可以通信。

5、postMessage

postMessage是HTML5标准中的API,它可以给我们解决如下问题:

  • 页面和新打开的窗口间数据传递
  • 多窗口之间数据传递
  • 页面与嵌套的 iframe 之间数据传递
  • 上面三个场景之间的跨域传递

postMessage 接受两个参数:

  • 参数一:发送的数据
  • 参数二:你要发送给谁就写谁的地址(协议 + 域名 +端口),也可以设置为*,表示任意窗口,为/表示与当前窗口同源的窗口
/**
* localhost:10002/index页面
**/
// 接收消息
window.addEventListener('message', (e) => {
     console.log(e.data)
})
// 发送消息
const targetWindow = window.open('http://localhost:10001/user');
setTimeout(()=>{
     targetWindow.postMessage('来自10002的消息', 'http://localhost:10001')
}, 3000)
/**
* localhost:10001/user页面
**/
window.addEventListener('message', (e) => {
     console.log(e.data)
     if (event.origin !== "http://localhost:10002") 
     return;
     e.source.postMessage('来自10001的消息', e.origin)
})

6、JSONP

原理就是通过添加一个<script>标签,向服务器请求JSON数据。服务器收到请求后,将数据放在一个callback回调函数中传回来(callback函数在请求JSONP之前已经定义好)。比如axios。

但是只支持GET请求并且可能遭受XSS攻击,好处是可以向老浏览器或不支持CORS的网站请求数据。

    let script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = 'http://juejin.com/xxx?callback=handleCallback'
    document.body.appendChild(script)
    
    function handleCallback(res){
        console.log(res)
    } //由于变量提升,在请求JSONP时cb函数已经存在,并且可以被执行

服务器返回并立即执行

handleCallback({ code: 200, msg: 'success', data: [] })

智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头和超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家和地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值