今天分享一下利用代理服务器实现跨域访问的案例。在这个案例中通过代理服务器我们动态获取到别的网络的响应体内容,从而实现自身页面的瀑布流效果
所谓瀑布流效果就是懒加载(就是为了防止重复执行同一个程序,点击过快,重复请求等例子,通常定义个开关变量防止重复执行),随着页面的滚动新的内容就加载出来了。效果图如下:
此页面用到的图片文字内容都是从别的网址拿到的响应体内容,这样很方便,我们不用写那么多标签了,动态生成内容,也不用保存那么多图片进行添加,这些都可以通过代理服务器请求获得别的网址的响应体内容进行添加
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 正确显示网络来源图片 -->
<meta name="referrer" content="never">
<title>Document</title>
<link rel="stylesheet" href="./bootstrap-3.3.7-dist/css/bootstrap.min.css">
<style>
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
a {
text-decoration: none;
}
img,
a {
width: 100%;
height: 100%;
display: block;
}
.box {
width: 1200px;
margin: 30px auto;
}
.box::after {
content: "";
display: block;
clear: both;
}
.box>ul {
width: 260px;
float: left;
margin-right: 30px;
}
.box>ul>li {
width: 100%;
display: flex;
flex-direction: column;
border: 1px solid red;
}
.box>ul>li>.imgBox {
width: 100%;
}
.box>ul>li>.contentBox {
width: 100%;
padding: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.box>ul>li>.contentBox>p {
display: flex;
justify-content: flex-start;
align-items: center;
}
.box>ul>li>.contentBox>p:nth-child(2)>i {
margin: 0px 10px;
}
.box>ul>li>.contentBox>p:nth-child(2)>span {
color: orange;
}
.box>ul>li>.contentBox>p:nth-child(3)>span:nth-child(1) {
width: 24px;
height: 24px;
border-radius: 50%;
overflow: hidden;
}
.box>ul>li>.contentBox>p:nth-child(3)>span:nth-child(2) {
margin-left: 10px;
display: flex;
flex-direction: column;
}
</style>
</head>
<body>
<div class="box">
<!-- 一列是一个ul,这里有四个,页面上显示就是四列 -->
<ul class="content"></ul>
<ul class="content"></ul>
<ul class="content"></ul>
<ul class="content"></ul>
</div>
<script>
// 记录请求数据起始位置
let start = 0;
// 开关变量,防止一直请求
let bool1 = '原始数值';
// 找到所有的ul
const oUls = document.querySelectorAll('.box ul');
// 调用函数
getData();
function getData() {
if (bool1 !== '原始数值') { return; }
bool1 = '非原始数值';
const xhr = new XMLHttpRequest();
// 通过代理服务器的地址,之后写网址后的参数
xhr.open('get', `/dt?include_fields=top_comments%2Cis_root%2Csource_link%2Citem%2Cbuyable%2Croot_id%2Cstatus%2Clike_count%2Csender%2Calbum%2Creply_count&filter_id=%E7%BE%8E%E9%A3%9F%E8%8F%9C%E8%B0%B1&start=${start}&_=1587714668214`);
// 发送请求
xhr.send();
// 接收到响应体内容
xhr.onload = function () {
if (xhr.readyState == 4 && /^2\d{2}$/.test(xhr.status)) {
// 请求到数据信息,但是是json格式字符串,需要转换为原数据
// console.log(JSON.parse(xhr.response));
// 获取请求结果,对象类型
const obj = JSON.parse(xhr.response);
// console.log(obj.data.next_start);
// 下次请求的起始数据,第一次是0开头,下次是24开头
start = obj.data.next_start;
// data.object_list 其中存储的是本次请求的24组数据,是数组类型
const dataArr = obj.data.object_list;
// console.log(dataArr);
// 循环遍历数组取到相关数据添加到标签中
dataArr.forEach((val) => {
// 先根据原始 图片比例,等比例缩小,计算现在li的高度,这样写就算图片没加载出来,也会知道高度
// 260是ul一开始大小,可以通过方法获取,这里偷懒直接写
let divHeight = (val.photo.height / val.photo.width) * 260;
let str = `<li>
<div class="imgBox" style="height:${divHeight}px">
<a href="JavaScript:;">
<img src="${val.photo.path}";alt="">
</a>
</div>
<div class="contentBox">
<p>${val.msg}</p>
<p>
<i class="glyphicon glyphicon-thumbs-up"></i><span>${val.like_count}</span>
<i class="glyphicon glyphicon-heart"></i><span>${val.favorite_count}</span>
</p>
<p>
<span>
<a href="JavaScript:;">
<img src="${val.sender.avatar}" alt="">
</a>
</span>
<span>
<strong>${val.sender.username}</strong>
<strong>${val.album.name}</strong>
</span>
</p>
</div>
</li>`;
// 先给最矮的ul加入数据,否则会对不齐
// 选择排序找出最矮的ul存储li
let minUl = oUls[0];
let minUlHeight = oUls[0].clientHeight;
oUls.forEach((val, key) => {
if (minUlHeight > val.clientHeight) {
// 找出最小的ul
minUl = val;
minUlHeight = val.clientHeight;
}
});
// 给最小的的ul加上li标签
minUl.innerHTML += str;
});
// 数据加载完成后才可以继续加载请求
bool1 = '原始数值';
}
}
// 滚动条事件
window.onscroll = function () {
// 获取滚动条上卷高度
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
// 获取视窗窗口的高度
let windowHeight = document.documentElement.clientHeight;
// 获取最矮ul的高度
let minUl = oUls[0];
let minUlHeight = oUls[0].clientHeight;
// 循环遍历所有的ul进行比较
oUls.forEach(function (item) {
// 如果循环当前的ul高度,小于存储的最小高度
if (item.clientHeight < minUlHeight) {
// 存储,当前ul标签对象,和当前ul标签的高度
minUl = item;
minUlHeight = item.clientHeight;
}
})
// 判断最矮高度要显示完的时候
// 不能让 最矮ul正好显示完,要留有一个余量,这样看起来就是连载,这个数值,可以自己定义
if (scrollTop + windowHeight > minUlHeight - 400) {
// 发送新的请求
getData();
}
}
}
</script>
</body>
</html>
下图是浏览器滚动事件涉及到的高度问题解释图片
注意: 中文文件名进行访问时都会出问题,尽量都用字母下划线进行文件命名
还有最重要的是要设置代理服务器,我这里用的是nginx服务器,需要改下nginx的配置文件,文件名是nginx.conf
修改如下:
这里就是在文件中找到server{}
大约是在56行左右,在这个里面任何位置写都可以,加上以上如图,设置需要跨域的ur地址就成功设置好代理服务器了。这个案例中用的是图片中的第二个
ajax
的具体解释练习可以参考Ajax交互小案例