跨域(跨源):越过、超出,某个区域,某个范围。
不同源就叫跨域
源(协议、域名、端口)
同源策略:是一种约定,它是浏览器最核心也最基本的安全功能。
同域名、同端口、同协议。就叫同源
只要控制台出现 Access-Control-Allow-Origin 就是跨域了。
解决跨域问题的几种方案:
1.设置(Access-Control-Allow-Origin)请求头,服务器得同意。 <高版本才能用>
CORS:是一个W3C标准,全称是“跨域资源共享”(Cross-origin resource sharing)
浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加请求,但用户不会有感觉,因此,实现CORS通信的关键是*服务器*。
只要服务器实现了CORS接口,就可以跨源通信。高版本的XMLHttpRequest + 服务器权限解决跨域问题
fetch 跨域请求举例:
1.GET
前端代码
fetch('http://localhost:6888/test_get?token=xxx&id=xxx',{ // 参数放在路径的查询信息里 method: 'GET', mode: 'cors', // cors 方式跨域 }).then(res => { return res.json(); }).then(json => { console.log('获取的结果', json.data); return json; }).catch(err => { console.log('请求错误', err); })
后端代码相关配置
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST")
响应(response)头部特殊部分
Access-Control-Allow-Origin:*
...
2.POST
前端代码
fetch('http://localhost:6888/test_post',{ method: 'POST', body: JSON.stringify({name: 'zaozuo'}), mode: 'cors', }).then(res => { return res.json(); }).then(json => { console.log('获取的结果', json.data); return json; }).catch(err => { console.log('请求错误', err); })
后端代码同get相同
响应(response)头部特殊部分同get相同
3.PUT
...很少用不介绍
2.服务器代理
通过服务器的文件能访问第三方数据。这个服务器文件又和当前请求的页面同源。这个时候,当前请求的页面去访问服务器文件,就等同于直接请求第三方资源。
2.1 React 中设置代理 ***
在package.json文件中设置 proxy
{ "name": "shenghuoyijia", "version": "0.1.0", "proxy": "http://localhost:9999/" }
看一下接口如何写
// get fetch('/userData').then(req=>req.json()) .then(data=>{ console.log(data) //请求到的数据 }) // post fetch('/userData',{ method:"post", headers:{ "Content-Type":"application/json" }, body:JSON.stringify({//请求的参数 user:'zhang666', age:21, }) }).then(res=>res.json()) .then(data=>{ console.log(data) //请求的结果 })
添加 "proxy": "http://localhost:9999/"这行代码
注:http://localhost:9999/ 为请求的端口号。以上例子中请求的完整地址实际是http://localhost:9999/userData
2.2 使用中间件
在Vue、React中:(课件、视频:2019-02-18)
react-create-app 跨域 通过 porxy 去跨域:
1)找到DevServer 文件 —>start.js
2)里面引入 setupProxy.js (跨域的中间件)
require('../src/setupProxy')(devServer);
setupProxy文件中有:
const proxy = require("http-proxy-middleware"); module.exports = function(app) { app.use(()=>{ proxy("/api",{ target:'跨域的地址', changeOrigin:true }); }) }
3)可以用 axios ,也可以用 fatch, .....
axios.get('/api?json=true') .then(e=>{ console.log(e); });
3.jsonp (json+padding) 把数据内填充起来。其实就是函数调用。 (长得像这样:fn({......})) <所有浏览器都兼容>
<link href = " "> 会尽可能解析css代码 <img src = " " >
<script src = " "> 会尽可能解析javaScript代码(引入的文件,和后缀名关系不大,和里面的代码关系才大。比如可以引入txt / ese...都是可以读的)
script 标签中的 src 能够直接跨域访问资源,并且尽量解析 js 代码。
jsonp 必须具备以下条件:
1.保证全局有个函数
2.数据必须是这个函数的调用格式
3.当要请求数据的时候,创建一个script标签,把src等于请求的接口
再把script标签插入到页面,这个时候就做到了按需请求。
例子:
function fn2(data) { console.log(data); }; //window.onload = function () { document.onclick = function () { let oS = document.createElement('script'); oS.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=小燕子&cb=fn2'; //oS.src = 'http://localhost/jsonp?callback=fn2'; document.getElementsByTagName('head')[0].appendChild(oS); oS.remove(); } //}