关于ajax跨域实战的一个小demo(真正的干货上篇)

2017-07-18  本文已影响0人  学习狂魔
jsonp1.png jsonp.png jsonp2.png
众所周知,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>

上一篇下一篇

猜你喜欢

热点阅读