解决跨域--jsonp
几种常用跨域方式区别:
jsonp : 前端来完成
CORS: 前后端配合完成 (存在预检请求的情况)
后端代理: 后端完成
简易版蘑菇街前端页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/index.css" />
<script src="jsonp.js"></script>
</head>
<body>
<div class="wrap">
<div class="headerContainer">
<img src="https://s10.mogucdn.com/mlcdn/c45406/190102_088f4i166l4gkl08k297h5kk8690i_260x200.png">
<div class="catalog">
目录
</div>
<div class="searchContainer">
<input type="text" class="searchInput" />
<button class="btn"></button>
</div>
<div class="iconShow">
<span class="iconMessage"></span>
消息
</div>
<div class="iconShow">
<span class="iconCollect"></span>
收藏
</div>
</div>
<h3 class="sub_title">
箱包
</h3>
<div class="nav_box">
<div class="txt">
<span>¥</span>
</div>
<span class="divid">-</span>
<div class="txt">
<span>¥</span>
</div>
<a class="confirm_btn" href="javascript:;">确定</a>
</div>
<div class="itemContainer">
<!-- 商品呈现 -->
<!-- <div class="item">
<img
src="https://s11.mogucdn.com/mlcdn/c45406/180830_0ggfhcfd757g3jg8k8fjaclc3h123_640x960.jpg_440x587.v1cAC.40.webp" />
<div class="bottom-describe">
<p class="describe">
海底捞火锅1盒懒人自煮自热方便速食牛油麻辣即食小火锅麻辣火锅
</p>
<div class="priceContainer">
<b>¥26.8</b>
<span class="oldPrice">¥53.6</span>
<span class="mystar">
<img src="https://s18.mogucdn.com/p2/160908/upload_27g4f1ch6akie83hacb676j622b9l_32x30.png"
alt="" />
2585
</span>
</div>
</div>
</div> -->
</div>
</div>
<script>
let page = 1;
getData();
function getData(){
ajax({
url:"https://list.mogu.com/search",
dataType:'jsonp',
jsonp:"callback",
data:{
_version:8193,
ratio:'3%3A4',
cKey:15,
page:page,
sort:'pop',
ad:0,
// fcid:50025,
action:'bags'
},
success:function(res){
// console.log(res);
if(res.status.code === 1001){
page++;
let data = res.result.wall.docs;
data.forEach(v => {
createElement(v);
});
}
}
});
};
function createElement(item){
// console.log(item);
let mydiv = document.createElement("div");
mydiv.classList = "item";
mydiv.innerHTML = `
<img src="${item.img}" />
<div class="bottom-describe">
<p class="describe">
${item.title}
</p>
<div class="priceContainer">
<b>¥${item.price}</b>
<span class="oldPrice">¥${item.orgPrice}</span>
<span class="mystar">
<img src="https://s18.mogucdn.com/p2/160908/upload_27g4f1ch6akie83hacb676j622b9l_32x30.png"
alt="" />
${item.sale}
</span>
</div>
</div>
`;
document.querySelector(".itemContainer").appendChild(mydiv);
};
//下拉加载
document.onscroll = function(){
let winH = document.documentElement.clientHeight;
let conH = document.documentElement.offsetHeight;
let scrollH = conH - winH;
let scrollT = document.documentElement.scrollTop;
if(scrollT >= (scrollH-5)){
getData();
}
}
</script>
</body>
</html>
简易版百度jsonp小示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="jsonp.js"></script>
</head>
<body>
<h1>百度搜索</h1>
<input type="text" class="myInput">
<div class="exchange"></div>
<script>
document.querySelector('.myInput').onblur = function(){
ajax({
url:'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
dataType:'jsonp',
data:{
wd:this.value
},
success:function(res){
console.log(res);
let data = res.s;
let html = "<ul>"
data.forEach(v => {
html += "<li>" + v + "</li>"
});
html += "</ul>";
document.querySelector(".exchange").innerHTML = html;
}
});
}
</script>
</body>
</html>
jsonp.js封装文件:(封装方式很多)
function ajax(options) {
let opts = Object.assign({
method: 'get', // josnp 只能用get请求,不可以post
url: '',
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
jsonp:"cb",
data: '',
success: function () { } // 请求完成之后触发的函数
}, options)
//处理jsonp请求;
if(opts.dataType==="jsonp"){
jsonpFn(opts.url,opts.data,opts.jsonp,opts.success);
return false;
}
function jsonpFn(url,data,cbName,cbFn){
// cbName cb/callback
let fnName = "KKB_"+Math.random().toString().substr(2);
window[fnName] = cbFn;
let path = url+"?"+o2u(data)+"&"+cbName+"="+fnName;
// console.log(path);
let o = document.createElement("script");
o.src = path;
document.querySelector("head").appendChild(o);
}
let xhr = new XMLHttpRequest();
if (options.method == "get") {
let data = o2u(opts.data)
options.url = options.url + "?" + data;
}
xhr.open(options.method, options.url, true);
for (let key in opts.headers) {
xhr.setRequestHeader(key, opts.headers[key]);
}
let sendData;
switch (opts.headers['content-type']) {
case 'application/x-www-form-urlencoded':
sendData = o2u(opts.data);
break;
case 'application/json':
sendData = JSON.stringify(opts.data);
break;
}
xhr.onload = function () {
let resData;
if (xhr.getResponseHeader("content-type").includes("xml")) {
resData = xhr.responseXML;
} else {
resData = JSON.parse(xhr.responseText);
}
options.success(resData);
}
if (options.method == "get") {
xhr.send();
} else {
xhr.send(sendData);
}
}
function o2u(obj) {
let keys = Object.keys(obj);
let values = Object.values(obj);
return keys.map((v, k) => {
return `${v}=${values[k]}`;
}).join("&");
}