一、ajax 原理 和 使用

ajax,即在不重新加载整个网页的情况下,对网页的某部分进行更新。

下面演示ajax 的实现原理

配置:

cd ajax

参考:http://www.expressjs.com.cn/starter/generator.html

express --view=ejs myapp
cd myapp
npm install

1、完整的ajax流程:

(1)、 创建XMLHttpRequest对象

var xhr = new XMLHttpRequest();

(2)、准备发送

 xhr.open('get', './01check.js?username='+uname+'&password='+pw,true);

(3)、执行发送动作

 xhr.send(null);

(4)、监听response 回调函数

onreadystatechange 事件:每当 readyState 改变时,就会触发 onreadystatechange 事件。

2、代码逻辑

index.js 路由

......
router.get('/api/one',(req,res,next)=>{
res.json({
status:200,
result:'this is one.....'
})
}); /* GET home page. */
router.get('/one', function(req, res, next) {
res.render('index1', { title: 'Express' });
})
...........

index.ejs:

<body>
<button id="send">发送1个请求</button>
<script>
var btn = document.getElementById('send');
btn.addEventListener('click',function () {
// 使用原生的ajax 技术,发送一个网络请求
// 1.创建XMLHttpRequest对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} // 2.准备发送
/*
参数1: 请求方式 (get/post)
参数2: 请求url
参数3: 是否异步
*/
xhr.open('get','http://localhost:3000/api/one',true); // 3. 发送
xhr.send(); // 4. 监听服务器的响应
// 一旦服务器响应回来之后, 就会执行这个函数
xhr.onreadystatechange = function () {
console.log(xhr.readyState);
if(xhr.readyState === 4){ // 代表服务器已经给了响应, 不代表响应成功
if(xhr.status === 200){
console.log(xhr.response);
}
}
} });
</script>
</body> // 结果:
/*
2
3
4
{"status":200,"result":"this is one....."}
*/


index.js 路由:

router.get('/api/two',(req,res,next)=>{
console.log(req.query);
res.json({
status:200,
result:'this is two.....'
})
}); router.get('/two', function(req, res, next) {
res.render('index2', { title: 'Express' });
});

index2.ejs

<body>
<input id="account" type="text" name="account">
<input id="pwd" type="text" name="pwd">
<button id="send">发送一个请求</button>
<script>
window.onload=function () { var btn = document.getElementById('send');
btn.onclick = function () {
// 使用原生的ajax 技术,发送一个网络请求
// 1.创建XMLHttpRequest对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} // 从页面获取需要传递的数据
var userName = document.getElementById('account').value;
var pwd = document.getElementById('pwd').value; // 2.准备发送
/*
参数1: 请求方式 (get/post)
参数2: 请求url
参数3: 是否异步
*/
// 后面跟一个随机数值,保证每次发送ajax请求,都是真的发然后从响应中获取最新数据,而不是从缓存中取得
xhr.open('get', 'http://localhost:3000/api/two?account=' + account + '&pwd=' + pwd + '&random=' + getRandomStr(), true); // 3. 发送
xhr.send(); // 4. 监听服务器的响应
// 一旦服务器响应回来之后, 就会执行这个函数
xhr.onreadystatechange = function () {
// 5. 处理响应的数据 (对方说话)
console.log(xhr.readyState);
if(xhr.readyState === 4){ // 代表服务器已经给了响应, 不代表响应成功
if(xhr.status === 200){
console.log(xhr.response);
}
}
}
}
} function getRandomStr() {
return Math.random() + (new Date().getTime())
}
</script> </body>

前端打印:

2
3
4
{"status":200,"result":"this is two....."}

服务端打印:

{ account: '[object HTMLInputElement]',
pwd: '123456',
random: '1547356096169.2708' }
GET /api/two?account=[object%20HTMLInputElement]&pwd=123456&random=1547356096169.2708 200 8.824 ms - 42


封装ajax:

AjaxTool.js:

(function (window) {
function AjaxTool() {} AjaxTool.ajaxRequest = function (url, paramObj, timeout, successCallBack, errorCallBack) {
// 1.创建XMLHttpRequest对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} // 2.准备发送
/*
参数1: 请求方式 (get/post)
参数2: 请求url
参数3: 是否异步
*/
// 后面跟一个随机数值,保证每次发送ajax请求,都是真的发然后从响应中获取最新数据,而不是从缓存中取得
var params_str = getStrWithObj(paramObj);
var uri_str = url + '?' + params_str;
// 转码
var codeURI = encodeURI(uri_str)
xhr.open('get', codeURI, true); // 3. 发送
xhr.send(); // 4. 监听服务器的响应
xhr.onreadystatechange = function () {
// 5. 处理响应的数据
console.log(xhr.readyState);
if(xhr.readyState === 4){ // 代表服务器已经给了响应, 不代表响应成功
if(xhr.status === 200){
successCallBack(xhr);
}else {
errorCallBack(); }
}
} // 5. 控制请求的时间
var timer;
if(timeout > 0){
timer = setTimeout(function () {
// 取消ajax 请求
xhr.abort();
},timeout);
} }
/*
* 把对象转换成字符串
* */
function getStrWithObj(paramsObj) {
var arr = [];
for(var k in paramsObj){
var str = k + '=' + paramsObj[k];
arr.push(str);
}
arr.push('random='+ getRandomStr());
return arr.join('&');
} /*
返回一个随机数
* */
function getRandomStr() {
return Math.random() + (new Date().getTime())
} window.AjaxTool = AjaxTool;
})(window);

index3.ejs:

<body>
<input id="account" type="text" name="account">
<input id="pwd" type="text" name="pwd">
<button id="send">发送一个请求</button>
<script>
window.onload=function () { var btn = document.getElementById('send');
btn.onclick = function () {
// 使用原生的ajax 技术,发送一个网络请求
// 1.创建XMLHttpRequest对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} // 从页面获取需要传递的数据
var userName = document.getElementById('account').value;
var pwd = document.getElementById('pwd').value; // 2.准备发送
/*
参数1: 请求方式 (get/post)
参数2: 请求url
参数3: 是否异步
*/
// 后面跟一个随机数值,保证每次发送ajax请求,都是真的发然后从响应中获取最新数据,而不是从缓存中取得
xhr.open('get', 'http://localhost:3000/api/two?account=' + account + '&pwd=' + pwd + '&random=' + getRandomStr(), true); // 3. 发送
xhr.send(); // 4. 监听服务器的响应
// 一旦服务器响应回来之后, 就会执行这个函数
xhr.onreadystatechange = function () {
// 5. 处理响应的数据 (对方说话)
console.log(xhr.readyState);
if(xhr.readyState === 4){ // 代表服务器已经给了响应, 不代表响应成功
if(xhr.status === 200){
console.log(xhr.response);
}
}
}
}
} function getRandomStr() {
return Math.random() + (new Date().getTime())
}
</script> </body>

3、简单版原生 post方式

<body>
<input id="account" type="text" name="account">
<input id="pwd" type="text" name="pwd">
<button id="send">发送一个请求</button>
<script>
window.onload=function () {
var btn = document.getElementById('send');
btn.onclick = function () {
// 1. 获取数据
var account = document.getElementById('account').value;
var pwd = document.getElementById('pwd').value; // 第一步
var xhr = new XMLHttpRequest();
// 第二步
xhr.open('post','http://localhost:3000/api/four',true)
// 第三步
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('account='+account + '&pwd=' + pwd); // 第四步
xhr.onreadystatechange = function () {
console.log(xhr.readyState);
console.log(xhr.status);
if(xhr.readyState === 4 && xhr.status === 200){
console.log(xhr.responseText);
}else {
console.log('请求失败');
}
} }
} </script> </body>

4、ajax 完整封装

(function(window){
function AjaxTool(){}
AjaxTool.ajaxRequest = function(params,successCallBack,errorCallBack){
// 0. 获取参数
var requestType = params['requestType'] || 'get';
var url = params['url'];
var paramsObj = params['paramsObj'];
var timeout = params['timeout'];
console.log(params);
// 1.创建XMLHttpRequest对象 (找到一个电话)
var xhr;
if(window.XMLHttpRequest){
xhr =new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} // 2.判断请求方式
if(requestType.toLowerCase() === 'get'){
var codeURI = encodeURI(url + '?' + getStrWithObject(paramsObj));
xhr.open('get',codeURI,true);
xhr.send();
}else if(requestType.toLowerCase() === 'post'){
// 请求体
var codeParam = encodeURI(getStrWithObject(paramsObj));
xhr.open('post',url,true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
console.log(codeParam);
xhr.send(codeParam); } // 3. 监听服务器响应
xhr.onreadystatechange = function(){
// 3.1 处理响应数据
if(xhr.readyState === 4){
// 4 代表服务器给响应了,并不代表响应成功
if(xhr.status === 200){
successCallBack(xhr);
// 清除定时器
clearTimeout(timer);
}else{
errorCallBack();
}
}
} // 4. 控制响应时间
var timer;
if(timeout > 0){
timer = setTimeout(function(){
// 取消ajax请求
xhr.abort();
},timeout);
} } /*
返回一个随机数
*/
function getRandomStr(){
return Math.random() + (new Date().getTime());
} /*
把对象转成字符串
*/
function getStrWithObject(paramsObj){
var arr = [];
for(var key in paramsObj){
var str = key + '=' + paramsObj[key];
arr.push(str)
}
arr.push('random=' + getRandomStr())
return arr.join('&');
}
window.AjaxTool = AjaxTool;
})(window)

index5.ejs:

<body>
<input id="account" type="text" name="account">
<input id="pwd" type="text" name="pwd">
<button id="send">发送一个请求</button>
<script src="../js/AjaxTool.js"></script>
<script>
window.onload=function () {
var btn = document.getElementById('send');
btn.onclick = function () {
// 1. 获取数据
var account = document.getElementById('account').value;
var pwd = document.getElementById('pwd').value; // 2. 处理数据
var paramsObj = {
'account':account,
'pwd':pwd
} var params = {
'requestType':'post',
'url':'http://localhost:3000/api/five',
'paramsObj':paramsObj,
'timeout':2000
} AjaxTool.ajaxRequest(params,function (xhr) {
console.log('成功' + xhr.responseText);
},function () {
console.log('失败');
}); }
} </script> </body>

index.js 服务端路由文件:

router.get('/five',(req,res,next)=>{
res.render('index5')
}); router.post('/api/five',(req,res,next)=>{
console.log(req.body);
res.json({
status:200,
result:'this is five...method:post..'
})
});

访问:http://localhost:3000/five

输入admin 123456 ,然后提交

前端打印:成功{"status":200,"result":"this is five...method:post.."}

服务端打印:{ account: 'admin', pwd: '123123', random: '1547522571613.208' }

5、用 jquery 进行 ajax 请求

三方封装的是最完善的,我们用三方封装好的即可,但是对ajax原生的执行的大致逻辑知道一些比较好。

index6.ejs:

<body>
<form action="http://localhost:3000/api/six" method="post">
<input id="account" type="text" name="account">
<input id="pwd" type="text" name="pwd">
<input id="send" type="submit" value="请求">
</form>
<script src="/js/jquery.js"></script>
<script>
$('form').on('submit', function () {
console.log($(this).serialize()); //account=admin&pwd=123456
$.ajax({
url: $(this).attr('action'),
type: $(this).attr('method'),
data: $(this).serialize(),
success: function (data) {
console.log(data); //{status: 200, result: "this is six...."}
}
}); // 阻止默认事件
return false;
});
</script>

服务端:

router.post('/api/six',(req,res,next)=>{
console.log(req.body);
res.json({
status:200,
result:'this is six....'
})
});

二、跨域

1、什么是跨域

同源策略:

2、解决方案:

jsonp
document.domain+iframe :只有主域名相同的情况下方可使用此方法
location.hash + iframe
window.name + iframe
window.postMessage
flash等第三方插件

3、跨域演示

express-generator 快速创建一个应用的骨架server,然后在服务端index.js 路由中

router.get('/', function(req, res, next) {
// res.render('index', { title: 'Express' });
console.log(`收到客户端的请求: ${req.url}`);
res.end('end');
});

在本地新创建一个页面,不要通过和 server 端口一致

<body>
<button id="send">点我</button>
<script src="js/AjaxTool.js"></script>
<script>
window.onload = function () {
var btn = document.getElementById('send');
btn.onclick = function () {
var paramObj = {
'name':'zhangsan',
'pwd':'123'
};
var params = {
'requestType' : 'get',
'url' : 'http://localhost:3000/',
'paramObj' : paramObj,
timeout : 2000
}; // 发起请求
AjaxTool.ajaxRequest(params,function (xhr) {
console.log('success...'+ xhr.responseText);
},function () {
console.log('failed.....');
})
}
}
</script> </body>

结果:

服务端还是收到请求了,打印:

收到客户端的请求: /?name=zhangsan&pwd=123&random=1547690599507.3115

GET /?name=zhangsan&pwd=123&random=1547690599507.3115 - - ms - -

客户端打印如下图:

4、jsonp 解决跨域问题

  • jsonp跨域必须前后端联合支持

  • jsonp只支持get不支持post

(1) 演示1

路由:

router.get('/',function (req,res,next) {
console.log(`收到客户端的请求: ${req.url}`);
var data = JSON.stringify({
status_code:200,
result:{
name:'张三',
age:19,
friend:['李四','王五','赵六']
}
});
res.end('getData('+data+')');
});

前端页面:

<body>
<script>
function getData(data) {
console.log(data);
}
</script>
<script src="http://localhost:3000/"></script>
</body>

通过 script 引入,来跨域请求,这个是可行的,同样的方式,还有 css标签的引入

(2) 封装

路由:

router.get('/',function (req,res,next) {
console.log(`收到客户端的请求: ${req.url}`);
var data = JSON.stringify({
status_code:200,
result:{
name:'张三',
age:19,
friend:['李四','王五','赵六']
}
});
console.log(`${req.query.callback}(${data})`);
res.end(`${req.query.callback}(${data})`);
});

前端:

<body>
<script> jsonp({
url: 'http://localhost:3000/',
data: '',
success: function (data) {
console.log(11111);
console.log(data);
}
});
jsonp({
url: 'http://localhost:3000/',
data: '',
success: function (data) {
console.log(22222); console.log(data);
}
}); /*
* 1、让函数名称不一致
* 2、调用完成后删除
* */
function jsonp(option) {
// 1. 将用户通过对象的命名空间传递进来的函数 挂载到全局
var callbackName = 'hello_' + Math.random().toString().substr(2);
window[callbackName] = function (data) {
option.success(data);
// 删除 script 标签 ,多次调用后 script 太多了,在这里删除掉
document.body.removeChild(script);
}; // 1. 处理url的拼接
option.url = option.url + '?callback=' + callbackName;
// 2. 创建script标签
var script = document.createElement('script');
script.src = option.url;
document.body.appendChild(script); /*说明: 拼接完url后,url 会带上函数的名称,服务端根据url 取得函数名称,然后返回的时候
res.end(`${req.query.callback}(${data})`);
* */
} </script>
</body>

前端代码注释:

加断点可以查看执行流程,首先 jsonp({})执行,接着到下面的 function jsonp({}),在下面的 function jsonp() 里面, window[callbackName] = function (data) {} ,在这里只是声明了函数,并且是全局的,但是并没有调用,里面的东西是在后来服务端 响应后调用的,并接着调用 了 里面的 option.success(data) 的函数,因为这个时候,服务端返回的时候把参数data 也传回来了 res.end(${req.query.callback}(${data})); 。所以接着执行了上面的 jsonp({}) 里面的 success:function(){data} 的函数。

执行结果:

三、nrm

什么是nrm:

install:

$ npm install -g nrm

查看有哪些源:

$ nrm ls

* npm -----  https://registry.npmjs.org/
cnpm ---- http://r.cnpmjs.org/
taobao -- https://registry.npm.taobao.org/
nj ------ https://registry.nodejitsu.com/
rednpm -- http://registry.mirror.cqupt.edu.cn
skimdb -- https://skimdb.npmjs.com/registry

选择镜像源:

$ nrm use cnpm  //switch registry to cnpm

    Registry has been set to: http://r.cnpmjs.org/

注意:每次安装包的时候,依然是使用 npm 命令来安装。

Ajax,跨域,nrm的更多相关文章

  1. Laravel中的ajax跨域请求

    最近接触Laravel框架ajax跨域请求的过程中遇到一些问题,在这里做下总结. 一开始发起ajax请求一直报500错误,搜索相关资料后发现Laravel要允许跨域请求可以加入Cors中间件,代码如下 ...

  2. Ajax操作如何实现跨域请求 (JSONP和CORS实现Ajax跨域的原理)

    由于浏览器存在同源策略机制,同源策略阻止ajax (XMLHttpRequest) 从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 特别的:由于同源策略是浏览器的限制,所以请求的发送和响 ...

  3. Ajax跨域问题的两种解决方法

    浏览器不允许Ajax跨站请求,所以存在Ajax跨域问题,目前主要有两种办法解决. 1.在请求页面上使用Access-Control-Allow-Origin标头. 使用如下标头可以接受全部网站请求: ...

  4. 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。

    ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...

  5. 解决ajax跨域请求 (总结)

    ajax跨域请求,目前已用几种方法实现:   1)用原生js的xhr对象实现.                var url="http://freegeoip.net/json/" ...

  6. Ajax跨域访问wcf服务中所遇到的问题总结。

    工具说明:vs2012,sql server 2008R2 1.首先,通过vs2012建立一个wcf服务项目,建立好之后.再新开一个vs2012 建立web项目,通过jQuery的ajax方法访问服务 ...

  7. JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  8. Ajax跨域:Jsonp原理解析

    推荐先看下这篇文章:JS跨域(ajax跨域.iframe跨域)解决方法及原理详解(jsonp) JavaScript是一种在Web开发中经常使用的前端动态脚本技术.在JavaScript中,有一个很重 ...

  9. jquery ajax跨域调用

    客户端: //ajax跨域调用的方法 $.ajax({ url:dustUrl+"/screenshot/getDevices.do", type: "get" ...

  10. 浅析JSONP-解决Ajax跨域访问问题

    浅析JSONP-解决Ajax跨域访问问题 很久没有写随笔了,总是感觉没时间,其实时间就是...废话少说,前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息.实现 ...

随机推荐

  1. 在linux命令行利用SecureCRT上传下载文件

    一般来说,linux服务器大多是通过ssh客户端来进行远程的登陆和管理的,使用ssh登陆linux主机以后,如何能够快速的和本地机器进行文件的交互呢,也就是上传和下载文件到服务器和本地?与ssh有关的 ...

  2. Redis学习笔记1 -- 单机环境时分布式锁的使用

    使用第三方开源组件Jedis实现Redis客户端,且只考虑Redis服务端单机部署的场景. 前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKee ...

  3. 滴滴开源 Vue 组件库— cube-ui

    cube-ui 是滴滴去年底开源的一款基于 Vue.js 2.0 的移动端组件库,主要核心目标是做到体验极致.灵活性强.易扩展以及提供良好的周边生态-后编译. 自 17 年 11 月开源至今已有 5 ...

  4. 无限滚动条的css布局理解

    一.需求描述 做一个waymo的滚动条,在页面中显示两张图,一共4张图,无限滚动播放. .car{ width: 600px; height: 157px; margin: 100px auto; b ...

  5. windows 2003 安装 MVC 环境 404错误,无法找到该页

    在windows server 2003 IIS6 系统安装 DotNet 4.0 + MVC3 环境后, .cshtml 文件依然无法运行,404错误 解决方案:查看处理程序隐射,如果没有.csht ...

  6. Codeforces Round #394 (Div. 2)

    前一半是刚刚打完比赛的时候写的……不知为啥手腕有点僵,估计是前一个小时用力过度了吧= = 前四题看着还好,后两题就有点懵逼了……现在还不知道E题的题意到底是啥…… 不管了……还没找着官方题解,贴一下自 ...

  7. React Native之React速学教程(下)

    概述 本篇为<React Native之React速学教程>的最后一篇.本篇将带着大家一起认识ES6,学习在开发中常用的一些ES6的新特性,以及ES6与ES5的区别,解决大家在学习Reac ...

  8. css3 animation运用

    animation:mymove 5s infinite; @keyframes mymove { from {left:0px;} to {left:200px;} } @-webkit-keyfr ...

  9. Eclipse开发工具printf打印方法提示报错的解决方法

    最近在学习java,在练习printf方法的使用时按照书上的语法配置却出现了报错.报错内容为:The method printf(String, Object[]) in the type Print ...

  10. 精准控制PWM脉冲的频率和数量

    在一些项目中,我们经常要控制PWM脉冲的频率和数量,比如步进电机的控制等,下面分享一个程序是关于这方面的,程序的思想就是通过STM32的定时器来输出PWM波,并开启定时器中断,在中断里面计数脉冲的数量 ...