整理的一些平时容易混淆的概念

描述cookie、sessionStorage和localStorage的区别

  • 场景应用不同:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。cookie由服务端生成,用于标识用户身份;而两个storage用于浏览器端缓存数据。
  • 存储大小限制也不同,cookie数据不能超过4k,因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
  • 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  • 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。

按照过期时间 cookie 分为两类:会话cookie和持久cookie。会话cookie是一种临时cookie,用户退出浏览器,会话cookie就会被删除了,持久cookie则会储存在硬盘里,保留时间更长,关闭浏览器,重启电脑,它依然存在,通常是持久性的cookie会维护某一个用户周期性访问服务器的配置文件或者登录信息。持久cookie 设置一个特定的过期时间(Expires)或者有效期(Max-Age),客户端会根据这个有效时间进行删除,如果不写,该有效时间默认为永久。

ajax,jsonp 与 cors

ajax 与 jsonp 的不同之处
  • 本质不同
    ajax 是一种发送 HTTP 请求与后台进行异步通讯从而实现局部刷新页面的技术,核心是通过 XMLHttpRequest 对象来获取服务端所提供的数据。
    jsonp 是数据格式 JSON 的一种“使用模式”,可以让网页从别的网域要数据,核心是利用 标签没有跨域限制的漏洞,服务端解析 URL 得到查询参数 callback,同时将这个 callback 参数值作为函数名来包裹住客户端所需要的 JSON 数据,从而实现获取服务端数据。
  • 请求方法不同
    ajax 可以发送 GET 和 POST 请求,而 jsonp 只能发送 GET 请求。
  • 补充
    它们的区别并不在于是否跨域,ajax 利用 cors 也能实现跨域,而 jsonp 也可以访问同域数据。

js 实现 ajax

///对发送数据的序列化
function serialize(data) {
    let arr = [];
    for(let key in data) {
        arr.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
    }
    return arr.join('&');
}
/**
 * @param {} params 
 * data: oebjct,
 * type: String('GET' OR 'POST'),
 * url: String,
 * success: Function,
 * error: Function
 */
function ajax(params) {
    params = params || {};
    params.data = params.data || {};
    params.type = params.type || 'GET';
    params.data = serialize(params.data);
    //如果是在ie6浏览器,那么XMLHttoRequest是不存在的,应该调用ActiveXObject;
    let xhr = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    if(params.type === 'GET') {
        xhr.open(params.type, params.url + '?' + params.data, true);
        xhr.send(null);
    } else {
        xhr.open(params.type, params.url, true);
                //设置表单提交时的内容类型
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(params.data);
    }
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
            var res;
            if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
                if(params.success && params.success instanceof Function) {
                    res = JSON.parse(xhr.responseText);
                    params.success.call(xhr, res);
                }
            } else {
                if(params.error && params.error instanceof Function) {
                    res = JSON.parse(xhr.responseText);
                    params.error.call(xhr, res);
                }
            }
        }
    }
}

jsonp 实现过程
1:首先声明一个用于处理服务器返回过来的数据的回调函数;
2:创建一个 <script> 标签,把跨域的API数据接口地址,赋值给 script 的 src,同时将前面创建的回调函数名加在地址的查询参数里,以便传给服务器端;
3:服务器接收到请求后,解析 url 获取传递过来的函数名,把函数名和想要返回给客户端的 JSON 数据(或者是其他格式的数据)拼接成一个字符串;
4:把上一步拼接成的字符串通过 HTTP 协议返回给客户端,于是这段 js 代码就可以调用回调函数,以此实现跨域数据访问。

简单代码实现:

//前端代码
function jsonp({ url, params, callback }) {
    return new Promise((resolve, reject) => {
        let script = document.createElement('script')
        window[callback] = function(data) {
            resolve(data)
            document.body.removeChild(script)
            window[callback] = null
        }
        params = { ...params, callback }
        let arrs = []
        for (let key in params) {
            arrs.push(`${key}=${params[key]}`)
        }
        script.src = `${url}?${arrs.join('&')}`
        document.body.appendChild(script)
    })
}
jsonp({
    url: 'http://localhost:3000/say',
    params: {
        wd: 'Iloveyou'
    },
    callback: 'show'
}).then(data => {
    alert(data)
})
//后端代码
let express = require('express')
let app = express()
app.get('/say', function(req, res) {
  let { wd, callback } = req.query
  console.log(wd) // Iloveyou
  console.log(callback) // show
  res.end(`${callback}('Iloveyoutoo')`)
})
app.listen(3000);

它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。实现 cors 的关键在于后端,与前端的关系在于是简单请求还是复杂请求。下面是一个复杂请求的 cors 跨域实例:

//前端代码
//发送一个ajax请求
let xhr = new XMLHttpRequest(); 
xhr.open('PUT', 'http://localhost:3000/test', true);
xhr.withCredentials = true;
xhr.setRequestHeader('name', 'xiamen');
xhr.send();
xhr.onreadystatechange = function() {
  if(xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText);
    console.log(xhr.getAllResponseHeaders());
    console.log(document.cookie);
    /*Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的 Cookie。*/
  }
}

//后端代码
let express = require('express');
let app = express();
let whiteList = ['http://127.0.0.1:8080'];
app.use((req, res, next) => {
  let origin = req.headers.origin;
  let cookie = req.headers.cookie;
  if(whiteList.includes(origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
    res.setHeader('Access-Control-Allow-Methods', 'PUT');
    // 表示服务器将会支持的请求头部值
    res.setHeader('Access-Control-Allow-Headers', 'name');
    // 允许携带cookie
    res.setHeader('Access-Control-Allow-Credentials', 'true');
    // 该字段可选,用来指定本次预检请求的有效期,单位为秒。
    res.setHeader('Access-Control-Max-Age', 5);
    // 允许返回的头
    res.setHeader('Access-Control-Expose-Headers', 'name');
    if(req.method === 'OPTIONS') {
      res.end();
    }  else if(!cookie) {
      res.setHeader('Set-Cookie', 'age=22');
    }
  }
  next();
});
app.put('/test', (req, res) => {
  console.log(req.headers);
  res.setHeader('name', 'lily');
  res.end('hello world!');
});

app.listen(3000, () => {
  console.log('server is running on port 3000.');
});

转载于:https://www.cnblogs.com/sunshine21/p/10223057.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值