必背-7.同源及跨域
同源与跨域
同源与跨域?
真实项目开发中,基本都是跨域的还是同源的?
- 开发环境:我们在本地开发项目,我们需要调用后台的接口,此时前后端代码基本不在一起,这样的访问是跨域的
- 生产环境:
- 如果我们把前后端代码放在同一个服务器下,这样数据的请求是同源的【很少】
- 一般我们都是分服务器部署[web服务器、数据服务器。。。]这样还是跨域【常用】
- 我们还会在自己的项目中,调用第三方平台的接口获取数据,这样的还是跨域请求!!
为什么会产生跨域?
- 服务器资源分离:WEB服务器、数据服务器、
- 云信息共享:第三方API接口
- 有助于分离开发:开发跨域、部署同源
解决跨域方法
如何解决跨域请求?
按常用优先级:
- 第一种:PROXY跨域代理&nginx反向代理【目前最常用】
- 第二种:CORS跨域资源共享
- 第三种:JSONP
其余方案:postMessage、document.domain+iframe、window.name、location.hash…【不常用了】
手撕JSONP
- 要点:
- 1、我们最终需要拼装出来一个
<script src="http://api.qq.com/?callback=func></script>" 这样的子串 - 2、在内部发送ajax请求,并处理最终的请求。
- 2、jsonp方法传的参数:
- url:路径
- options:配置项
- params:默认null,对象类型,问号后的参数信息
- jsonpName:‘callback’,基于哪个字段把全局函数名传递给服务器
(function () {
const isPlainObject = function isPlainObject(obj) {
let proto, Ctor;
if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
proto = Object.getPrototypeOf(obj);
if (!proto) return true;
Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
return typeof Ctor === "function" && Ctor === Object;
};
const stringify = function stringify(obj) {
let keys = Reflect.ownKeys(obj),
str = ``;
keys.forEach(key => {
str += `&${key}=${obj[key]}`;
});
return str.substring(1);
};
const jsonp = function jsonp(url, options) {
if (typeof url !== "string") throw new TypeError('url is not a string~');
if (!isPlainObject(options)) options = {};
let { params, jsonpName } = Object.assign(
{
params: null,
jsonpName: 'callback'
},
options
);
return new Promise((resolve, reject) => {
let name = `jsonp${+new Date()}`,
script;
window[name] = function (data) {
resolve(data);
if (script) document.body.removeChild(script);
Reflect.deleteProperty(window, name);
};
if (params && isPlainObject(params)) {
params = stringify(params);
url += `${url.includes('?') ? '&' : '?'}${params}`;
}
url += `${url.includes('?') ? '&' : '?'}${jsonpName}=${name}`;
script = document.createElement('script');
script.src = url;
script.async = true;
script.onerror = () => reject();
document.body.appendChild(script);
});
};
if (typeof module === 'object' && typeof module.exports === 'object') module.exports = jsonp;
if (typeof window !== 'undefined') window.jsonp = jsonp;
})();
|