众所周知,ajax技术只有在同源的前提下使用,我是刚入行的小白,才疏学浅,http的无状态协议的原则,也指导ajax访问非同域的api的时候回报一个不是同源的错,自己也是找了很久,才把这个东西解决,虽然玩的不6但是这个问题我已经知道怎么解决了,今天就分享一个demo,帮助大家彻底理解使用ajax调用非本地资源,说了这么多废话赶紧进入正题。
今天首先要准备一个api,我这边有两个api可以供大家选择,其中一个是已经写好的一个demo但是他不需要跨域这个我也不懂,其实是学来的。另外一个是自己发掘的,你们大家都可以使用,但是有一点我想说,就是如果你们相传到github上面的话,我有一个建议一定要找https协议的api,因为github不支持非https的一切api,又说了一堆废话,正式开始吧。
首先我想一下这二个demo的实现功能。
这个demo实现的就是一个ajax获取非同源数据的时候,用jsonp方式来获取,我这边将会给大家提供两种方式一种是原生js封装jsonp,另外一种方式就是调用jQuery封装好的ajax,我分两次说完,那么就开始了。
我先上一段效果吧给大家看一下,最终实现的效果是什么样的
大致说一下 这些图片还有文字都是通过ajax请求回来的而不是不过这个没有跨域我先讲这个是怎么实现的,当我第二篇的时候就把另外的demo一起说一下,因为如果直接上跨域还要说一下别的知识,html页面,有两个部分,一个是请求回来的图片数据和新闻链接,当你点击的时候会进入相应的网页具体的文章就会浮现出来,下面的几个按钮是我写的丑陋的分页按钮,但是他已经可以实现分页的功能了。每页请求的数目规定在api里面,我就把他们分成了几个页面加载,来实现一个分页的功能,说的可嫩不太清楚,来看代码吧。
首先这个api全称是 https://route.showapi.com/181-1?&showapi_appid=30603&showapi_sign=98960666afeb4992ae91971d13494090&num=10
showapi_appid:这就是一个公用的appid
showapi_sign:这个算是一个登陆密码吧,就这理解,我也是偶然得来的
num:这个参数是请求文章数目
=========================手动分割线===========================
这是公共用的数据库供大家学习。
下面开始讲代码
先分享思路,这个首先通过ajax对象获取我们想要的东西,这个要用到一个XMLHttpRequest 对象那我们先创建一个这个对象
这里用原生ajax
创建对象 我习惯用const
const xmlHttp = new XMLHttpRequest();
然后拆解我们的api,url
const url = 'https://route.showapi.com/181-1';
创建我们要发送的数据比如appid 等这些参数
所以
const sendData = {
showapi_appid: '30603',
showapi_sign: '98960666afeb4992ae91971d13494090',
num: 8 //每一页请求多少条数据
}
然后我们把url完整的拼接起来,有人可能问我为什么这么写,要写成对象的样子吧url拆解,我的理解是为了代码的健壮性,还有就是为了修改方便,不把他写死。
现在我们开始吧url拼接起来这里顺便复习一下扫描对象的方法for in 这个方法,
建立一个空数组来存放url的参数对象
let params = [ ]
for( let key in sendData){
params.push(key + '=' sendData[key] )
}
然后将数组中每一个元素用&拼接成字符串数组转字符串
const postData = parmas.join('&')
试着打印一下
console.log(postData)
然后用我们的XHR对象的方法连接url 之前把XRH存到了 xmlHttp中所以
xmlHttp.open('GET', url + '?' +postData ,true ) 这里异步请求默认可以不写 true
需要我们发送一个消息通常默认这个send的消息为空或者null
xmlHttp.send(null)
最后我们需要检查一下他状态,用到了一个onreadystateChange的事件
这个事件是检查返回状态是否正确的
判断一下这里有两个判断的一个状态1,2,3,4我们要让他走过这个四个步骤还有一个就是状态吗status=200的时候让他返回一些东西,或者执行一些东西。
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readtState===4&&xmlHttp.status===200){
let result = JSON.parse(xmlHttp.response); // 注意这里我们用JSON对象的parse方法把url接收回来的数据字符串编程json对象
let dataList = result.showapi_resbody.newlist // 注意这里 因为json对象里面一般有数组我们取他们的数组,这时候你需要查看一下之前
https://route.showapi.com/181-1?&showapi_appid=30603&showapi_sign=98960666afeb4992ae91971d13494090&num=10 这个api里面 直接打开 就可以看见 很容易的showapi_resbody对象相面
newlist 是一个数组 所以我们要那里面的东西并且把它放进我们dataList的变量里面 大家可以打印一下看一下你是不是应获取到这个 Object了呢
console.log(dataList)
}
}
以下是完整代码,可能有地方是多余或者有问题,大家可以修改,有什么建议请简讯我,谢谢大家支持。
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style>
.style{
border: 1px solid #333; height: 22px; width: 22px;
text-align: center;
float: left;
padding: 6px;
margin-top: 100px;
margin-left: 20px;
list-style: none;
}
</style>
</head>
<body>
<div class="content">
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<footer>
<ul class="Li" style=" cursor: pointer;">
<li class="style">1</li>
<li class="style">2</li>
<li class="style">3</li>
<li class="style">4</li>
<li class="style">5</li>
<li class="style">6</li>
</ul>
</footer>
<script >
//这边我使用了原生ajax对象来实现的这个demo html和css就是随便写的,大家可以自己改写。
let oCon = document.querySelector('.content'); //获取元素
let allLi = document.querySelectorAll('.style');
let page = 1;//页码初始化
pageList();
function pageList() {
//用var无法阻断for循环 采用let 块级作用
let len = allLi.length;
for (let i =0; i<len; i++){
allLi[i].onclick = function () {
// alert(i+1);
page = i;
getJson();
}
}
// 匿名体立即执行
/* for(var i=0, len = allLi.length ;i<len;i++){
(function (i) {
allLi[i].onclick = function () {
alert(i+1)
}
})(i)
}*/
}
getJson();
function showPage (dataList) {//页面渲染
let str = '';//初始化标签文本域
let len = dataList.length;//数组长度
for(let i=0 ;i<len ;i++){
str+=`<a style="text-decoration:none" href="${dataList[i].url}" >
![](http://www.tanzhouphp.com/tanzhoue/images/newsList/${1+(i%8)}.jpg)
<p >${dataList[i].title}
<span style="margin-left: 50px ; "> > </span></p>
</a>`
}
oCon.innerHTML =str; //渲染列表到content中
//console.log(str)
}
function getJson () { //数据拉取模块
const params = [];
const xmlHttp = new XMLHttpRequest();//创建对象
const url = 'https://route.showapi.com/181-1';
const sendData = {
showapi_appid: '30603',
showapi_sign: '98960666afeb4992ae91971d13494090',
page: page, //page 绑定到全局作用于page变量
num: 8
};
for(let key in sendData){//讲json键值对添加到数组
params.push(key + '=' + sendData[key]);
}
const postData = params.join('&'); //数组每一个元素以&拼接字符串
console.log(postData);
xmlHttp.open('GET',url + '?'+ postData,true);
console.log(url + '?'+ postData)
xmlHttp.send(null);
xmlHttp.onreadystatechange = function () {
if(xmlHttp.readyState===4&&xmlHttp.status===200){
let result = JSON.parse(xmlHttp.response);
let dataList = result.showapi_res_body.newslist;//数组
showPage(dataList);
console.timeEnd('数据拉取');
console.log(dataList)
}
};
}
</script>
</body>
</html>