每天两道面试题,巩固知识点

1px物理像素实现

在移动端web开发中,UI设计稿中设置边框为1像素,前端在开发过程中如果出现border:1px,测试会发现在某些机型上,1px会比较粗,即是较经典的移动端1px像素问题。

设备像素比dpr = 设备像素 / CSS像素(某一方向上) 可以通过window.devicePixelRatio获取设备的dpr值。一般来说,在桌面的浏览器中,设备像素比(dpr)等于1,一个css像素就是代表的一个物理像素。而在移动端,大多数机型都不是为1,其中iphone的dpr普遍是2和3,那么一个css像素不再是对应一个物理像素,而是2个和3个物理像素。即我们通常在css中设置的width:1px,对应的便是物理像素中的2px。手机机型不同,dpr可能不同。

以iphone5为例,iphone5的CSS像素为320px568px,DPR是2,所以其设备像素为640px1136px

解决方案一

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- initial-scale=1.0 缩放比 当为1的时候没用进行任何缩放 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>1px物理像素实现(方案一)</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #box {
            width: 0.5rem;
            height: 0.5rem;
            border-bottom: 1px solid #000;
        }
    </style>
    <!-- 像素比 = 物理像素 / css像素 -->
</head>

<body>
    <div id="box"></div>
</body>
<script type="text/javascript">
    window.onload = function () {
        //像素比是什么?针对不同屏幕 dpr不一样
        var dpr = window.devicePixelRatio;
        console.log(dpr);
        //缩放比例
        var scale = 1 / dpr;
        //可视区域的宽度
        var width = document.documentElement.clientWidth;
        //获取mate标签
        var metaNode = document.querySelector('meta[name="viewport"]');
        metaNode.setAttribute('content',"width=device-width, initial-scale='+scale+'");

        //页面中元素的宽度,高度,比例得反向乘回来
        var htmlNode = document.querySelector('html');
        htmlNode.style.fontSize = width * dpr + 'px';

    }
</script>
</html>
复制代码

解决方案二

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- initial-scale=1.0 缩放比 当为1的时候没用进行任何缩放 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>1px物理像素实现(方案二)</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #box {
            width: 200px;
            height: 200px;
            position: relative;
        }

        #box:before {
            content:'';
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 1px;
            background: #000;

        }
        @media screen and (-webkit-min-device-pixel-ratio:2) {
            #box:before {
                transform: scaleY(0.5);
            }
        }
        @media screen and (-webkit-min-device-pixel-ratio:3) {
            #box:before {
                transform: scaleY(0.333333);
            }
        }
    </style>
</head>

<body>
    <div id="box"></div>
</body>
<script type="text/javascript">
    window.onload = function () {

    }
</script>
</html>
复制代码

元素水平居中的方法

方法一

<style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            position: relative;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
            position: absolute;
            top:0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
复制代码

方法二

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            position: relative;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
            position: absolute;
            top:50%;
            left: 50%;
            margin-left:-25px;
            margin-top:-25px;
        }
    </style>
复制代码

方法三(css3)

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            position: relative;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
            position: absolute;
            top:50%;
            left: 50%;
            transform: translate(-50% , -50%);
        }
    </style>
复制代码

方法四(flex新版本)

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
        }
    </style>
复制代码

方法五(flex老版本)

<style type="text/css">
        #wrap {
            width: 100px;
            height: 100px;
            background:grey;
            display: -webkit-box;
            -webkit-box-pack:center;
            -webkit-box-align: center;
        }
        #wrap .box {
            width: 50px;
            height: 50px;
            background:pink;
        }
    </style>
复制代码

如何实现移动端rem适配

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>rem适配</title>
    <style type="text/css">
        #wrap {
            width: 0.5rem;
            height: 0.5rem;
            background:grey;
        }
        /* html 根元素字体大小设置屏幕区域的宽度 */
    </style>
</head>

<body>
    <div id="wrap">
        <div class="box"></div>
    </div>
</body>
<script type="text/javascript">
    window.onload = function () {
        //获取屏幕区域的宽度
        var width = document.documentElement.clientWidth;
        //获取html
        var htmlNode = document.querySelector('html');
        //设置字体大小
        htmlNode.style.fontSize = width + 'px';

    }
</script>
</html>
复制代码

什么是跨域?解决跨域的方法?

跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器施加的安全限制。

同源策略

- ——是浏览器安全策略
- ——协议名、域名、端口号必须完全一致
- 举例:
复制代码
http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)

http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)

http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

浏览器执行javascript脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行
复制代码

跨域

- 违背同源策略就会产生跨域
复制代码

解决方法

- jsonp cors websocket Node中间件代理(两次跨域) ngix反向代理...
复制代码

1. jsonp方法

所以JSONP的原理其实就是利用引入script不限制源的特点,把处理函数名作为参数传入,然后返回执行语句,仔细阅读以下代码就可以明白里面的意思了。

补充:1) JSONP和AJAX对比

    JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)
复制代码

2)JSONP优缺点

    SONP优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅支持get方法具有局限性,不安全可能会遭受XSS攻击。
复制代码
<script>
        //创建 script 标签
        var script = document.createElement('script');
        //设置回调函数
        function getData(data) {
            //数据请求回来被触发的函数
            console.log(data);
        }
        //设置script的src属性,设置请求地址
        script.src = 'http://localhost:3000?callback = getData';
        //让script生效
        document.body.appendChild(script);
    </script>
复制代码

2.cors的简单请求

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。 浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。 服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。 虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。

只要同时满足以下两大条件,就属于简单请求

扫描二维码关注公众号,回复: 6684125 查看本文章

条件1:使用下列方法之一:

  • GET
  • HEAD
  • POST

条件2:Content-Type 的值仅限于下列三者之一:

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器; XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。

4.websocket

Websocket是HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数据。 同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。 原生WebSocket API使用起来不太方便,我们使用 Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

我们先来看个例子:本地文件socket.html向 localhost:3000 发生数据和接受数据

// socket.html
<script>
    let socket = new WebSocket('ws://localhost:3000');
    socket.onopen = function () {
      socket.send('我爱你');//向服务器发送数据
    }
    socket.onmessage = function (e) {
      console.log(e.data);//接收服务器返回的数据
    }
</script>

复制代码
// server.js
let express = require('express');
let app = express();
let WebSocket = require('ws');//记得安装ws
let wss = new WebSocket.Server({port:3000});
wss.on('connection',function(ws) {
  ws.on('message', function (data) {
    console.log(data);
    ws.send('我不爱你')
  });
})

复制代码

总结:CORS支持所有类型的HTTP请求,是跨域HTTP请求的根本解决方案 JSONP只支持GET请求,JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。 不管是Node中间件代理还是nginx反向代理,主要是通过同源策略对服务器不加限制。 日常工作中,用得比较多的跨域方案是cors和nginx反向代理

更多方法参考:juejin.im/post/5c2399…

转载于:https://juejin.im/post/5d0a3422e51d4550723b1400

猜你喜欢

转载自blog.csdn.net/weixin_33716154/article/details/93182311