> 文章列表 > 【面试题】请求跨域相关面试题总结

【面试题】请求跨域相关面试题总结

【面试题】请求跨域相关面试题总结

一、面试题

1、什么是跨域

协议 + 端口 + 端口 三者必须相同。(同源策略)


2、为什么浏览器要遵循同源策略

如果缺少了同源策略,浏览器很容易受到 XSS、CSRF 等攻击


3、浏览器中哪些标签是运行跨域加载资源的

<img src=xxx><link href=xxx><script src=xxx>


4、请求跨域了,那么请求发送出去了没有?

跨域并不是请求发送不出去,请求能发送产前样,服务端能收到请求并正常返回结果,只不过结果被浏览器拦截了


5、那为什么表单能够跨域发送请求,而 Ajax 却不能发送跨域请求

  • 归根结底:跨域是为了阻止用户读取到另一个域名下的内容
  • 而 Ajax 可以获取响应,但浏览器认为这不安全,所以拦截了响应
  • 但是表单并不会获取新的内容,所以可以发起跨域请求。

前者是发送跨域请求给到后端,并不去接收服务器返回的信息

后者是发送跨域请求给到后端,并接收服务器返回的信息


二、解决跨域的方法

1、JSONP

JSONP 的原理是利用<script>标签的跨域特性,可以不受限制地从其他域中加载资源

function jsonp(options) {var script = document.createElement('script');// 参数处理var params = '';for (var attr in options.data) {params += '&' + attr + '=' + options.data[attr];} // 设置回调函数var successCallback =  `successCallback`;window[successCallback] = options.success;script.src = options.url + '?callback=' + successCallback + params;document.body.appendChild(script);
}

代码解释:但请求成功后,前端得执行回调函数,但 script 脚本是执行不到 success() 方法的。这是因为 success() 方法 并不是 全局函数

所以需要将 success() 方法 改成全局函数

var successCallback =  `successCallback`;
window[successCallback] = options.success;

并在请求参数的基础上,需要添加 callback 参数,值对应需要回调的函数名

script.src = options.url + '?callback=' + successCallback + params;

使用:

var btn = document.getElementById('btn');
btn.addEventListener('click', function() {jsonp({url: 'http://localhost:3001/getUserInfo',data: { name: '浩浩' },success: function(data) {alert('UserInfo:' + JSON.stringify(data));}})
});

JSONP 优缺点

  • 简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题
  • 仅支持get方法具有局限性,不安全可能会遭受 XSS 攻击

2、CORS

  • CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
  • CORS 需要浏览器和服务器同时支持。但是目前基本上浏览器都支持,所以我们只要保证服务器端服务器实现了 CORS 接口,就可以跨源通信

后端解决跨域问题,就是在服务器端给响应添加头信息

Name Required Comments
Access-Control-Allow-Origin 必填 允许请求的域
Access-Control-Allow-Methods 必填 允许请求的方法
Access-Control-Allow-Headers 可选 预检请求后,告知发送请求需要有的头部
Access-Control-Allow-Credentials 可选 表示是否允许发送cookie,默认false;
Access-Control-Max-Age 可选 本次预检的有效期,单位:秒;

2.1、在 Node 上处理

const Koa = require('koa')
const app = new Koa()app.all("*", (req, res, next) => {res.header("Access-Control-Allow-Origin", "*");res.header("Access-Control-Allow-Headers", "content-type");// 关键点next()
})
const Koa = require('koa')
const app = new Koa()app.all("*", (req, res, next) => {// 设置域名跨域res.header("Access-Control-Allow-Origin", "http://127.0.0.1");// 跨域允许的请求方式res.header("Access-Control-Allow-Headers", "DELETE,PUT,POST,GET,OPTIONS");// 关键点next()
})

2.2、在 Nginx 上处理

location /example {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Methods *;# add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}