一、什么是跨域?

当协定、(主/子)域名、端口号中任意一个不雷同时,都算作不同域,不同域之间相互申请资源,就称为跨域

1、什么是同源策略及其限度内容?

同源策略是一种约定,是指 协定、域名、端口 三者雷同,即使两个不同域名指向同一个ip地址,也非同源。

限度内容:

  • 同源策略限度内容有:Cookie、localStorage、IndexedDB
  • DOM 节点
  • AJAX申请
  • 但img、link、script这个三个标签是容许跨域加载资源的

2、常见跨域场景

特地阐明:

  • 如果是因为协定和端口造成的跨域问题,“前台”是无能为力的。
  • 判断是否跨域,仅仅是通过url比照来辨认的,并不会比照url对应的ip地址。
  • 当咱们申请服务器数据呈现跨域时,申请是能够失常收回的,服务端也能够收到返回后果,只是被浏览器拦挡了申请后果。

跨域解决办法

1、jsonp(原理及优缺点如下)

  • 受同源策略的影响,ajax不容许进行跨域申请,但<script>标签的src属性没有跨域限度,利用该个性,能够从其余跨域的url中获取的json数据,
  • 长处:JSONP兼容性较好,可用于解决支流浏览器的跨域问题,并且不须要XMLHttpRequest或ActiveX的反对,可能间接拜访响应文本,反对在浏览器与服务器之间双向通信。
  • 毛病:仅反对get办法,具备局限性,存在平安问题,例如:被歹意注入代码、蒙受xss攻打

2、JSONP实现过程

  • 在js中,咱们尽管不能间接用XMLHttpRequest申请不同域上的数据,但在页面上引入不同域的js文件是能够的,JSONP正是利用这一个性来实现的。
  • JSONP由两局部组成:回调函数和数据,回调函数是当响应到来时,应该在页面中调用的函数,而数据是传入回调函数中的JSON数据。
  • 创立一个<script>标签,将须要跨域拜访的接口地址赋值给src,并在该地址中向服务器传递函数名(能够应用?callback=XX函数名),
  • 服务器接管到申请后,把传递进来的函数名和它须要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它筹备好的数据是show('我不爱你')。
  • 最初服务器把筹备的数据通过HTTP协定返回给客户端,客户端再调用执行之前申明的回调函数(show),对返回的数据进行操作。

3、封装实现

在开发中可能会遇到多个 JSONP 申请的回调函数名是雷同的,这时候就须要本人封装一个 JSONP函数。
首先建一个启动本地服务的js,通过node启动后,即可拜访http://localhost:3000本地服务
// server.jslet express = require('express')let app = express()app.get('/say', function(req, res) {  let { wd, callback } = req.query  console.log(wd) // Iloveyou  console.log(callback) // show  res.end(`${callback}('我不爱你')`)})app.listen(3000)
而后在index.html中的script标签内运行该处代码
function jsonp({ url, params, callback }) {  return new Promise((resolve, reject) => {    let script = document.createElement('script')    window[callback] = function(data) {      resolve(data)      document.body.removeChild(script)    }    params = { ...params, callback } // wd=b&callback=show    let arrs = []    for (let key in params) {      arrs.push(`${key}=${params[key]}`)    }    script.src = `${url}?${arrs.join('&')}`    document.body.appendChild(script)  })}jsonp({  url: 'http://localhost:3000/say',  params: { wd: 'Iloveyou' },  callback: 'show'}).then(data => {  console.log(data)})