这是我参与更文挑战的第26天,活动详情查看: 更文挑战
1, CSS 伪元素 before after
1,作用:
伪元素的作用是在内容元素的前后插入额外的元素,但它是一个虚假的元素,不会影响内容元素的DOM节点
2,用法:
伪元素使用起来也比较容易,在CSS2.1的时候,一个冒号:表示伪元素。在CSS3中,为了区分伪类和伪元素,
用 :(一个冒号)表示伪类 :: (两个冒号)表示伪元素,目前在开发中,两种方式都行
3,注意:伪元素必须设置content属性,不然无效
4,常用案例:
(1) 分隔符, (2) 添加前置图标, (3) 三角形实现
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
ul {
list-style: none;
}
li {
position: relative;
display: block;
margin:15px;
}
li::before {
content: '';
background: url(dist/static/img/chop_min.eb28a5e.png) no-repeat;
background-size: 100%;
width:20px;
height:20px;
position: absolute;
left: -30px;
}
li:not(:last-child)::after {
content: '|';
padding:0 10px;
}
.demo {
width:0;
height: 0;
border: 40px solid transparent;
border-left: 40px solid #ff0000;
}
.test {
width:200px;
height: 50px;
line-height: 50px;
background:red;
}
.test::before {
display: inline-block;
content: '';
border: 5px solid transparent;
position: relative;
left: 200px;
border-left-color:red;
}
</style>
</head>
<body>
<ul>
<li>HTML5</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<p class="demo"></p>
<p class="test"></p>
</body>
</html>
5,效果截图
6,注意:
(1) content可以添加图片url(),但是没法修改图片大小,所以可以用背景图片替换该功能。
(2)如果li想横向排列,可以设置display: inline-block
2, CSS圣杯布局 && 双飞翼布局
1, 两者作用和区别:
圣杯布局和双飞翼布局解决的问题都是一样的。两边固定宽度,中间自适应的三栏布局,已经由此演变出来的类似其他布局格式。中间布局代码要写在 前边,保证第一个渲染
区别: 两者在布局的前三点方法是一样的,通过float浮动,和margin-left负值,让三元素并排显示。行成三栏布局,区别在中间盒子处理的方式。怎么做才能不把中间盒子的内容覆盖住。让其完全显示。
1, 圣杯布局是通过父元素设置padding-left和padding-right为左右两边的盒子留空间。然后左右两
盒子通过相对定位,改变left和right的值。移动后不遮挡中间div
2, 双飞翼布局是直接在中间div内部创建子div,用于放置内容。并且设置子div的margin-left和
margin-right,为左右两个div留出位置,左右两个盒子不需要设置position:relative和right,left属性。
个人感觉比圣杯布局要简单一些。具体操作参考下面代码
2,圣杯布局特点
(1)父元素包含三个元素,分别设置他们左浮动
(2)中间的盒子宽度设置为100%,自适应,并且在三个元素的最前面显示,第一个渲染
(3)左右两边使用margin-left的负值,使他们与中间的盒子同行,(左边:-100%,右边:-右边盒子的宽度)
(4)中间的盒子width:100%后,需要父元素通过padding设置左右两边空白,为左右两边的盒子留同等大小的空间
(5)设置左右两边position:relative,通过left移动位置
2,代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>圣杯布局</title>
<style type="text/css">
*{
margin:0;
padding:0;
}
.container {
height: 400px;
padding:0 200px;
overflow: hidden;
}
.middle {
width:100%;
height: 400px;
line-height: 400px;
float: left;
text-align: center;
background-color: #eeeeee;
}
.left {
position: relative;
width:200px;
height: 400px;
text-align: center;
line-height: 400px;
float: left;
margin-left: -100%;
left: -200px;
background-color: red;
}
.right {
position: relative;
width:200px;
height:400px;
text-align: center;
line-height: 400px;
float: left;
margin-left: -200px;
right: -200px;
background-color: green;
}
header, footer {
width:100%
height: 50px;
line-height: 50px;
text-align: center;
border: 1px solid deeppink;
background: pink;
}
</style>
</head>
<body>
<header>上</header>
<div class="container">
<div class="middle">中</div>
<div class="left">左</div>
<div class="right">右</div>
</div>
<footer>下</footer>
</body>
</html>
效果截图
3,双飞翼布局:
(1)(2)(3)同上
(4)给中间元素设置子元素,并给其设置其margin-left 和 margin-right值,为左右盒子留位置
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>双飞翼布局</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.container {
height: 400px;
overflow: hidden;
}
.middle {
width: 100%;
height: 400px;
line-height: 400px;
float: left;
text-align: center;
background-color: #eeeeee;
}
.middle > div {
margin: 0 200px;
background-color: #eeeeee;
}
.left {
width:200px;
height: 400px;
text-align: center;
line-height: 400px;
float: left;
margin-left: -100%;
background-color: red;
}
.right {
width: 200px;
height: 400px;
text-align: center;
line-height: 400px;
float: left;
margin-left: -200px;
background-color: green;
}
header,footer {
width:100%
height: 50px;
line-height: 50px;
text-align: center;
border: 1px solid deeppink;
background: pink;
}
</style>
</head>
<body>
<header>Header</header>
<div class="container">
<div class="middle">
<div>我是中间</div>
</div>
<div class="left">我是左边</div>
<div class="right">我是右边</div>
</div>
<footer>Footer</footer>
</body>
</html>
代码截图
3, CORS跨域
CORS是W3C标准。全场跨域资源共享(Cross-origin resourse sharing)
她允许浏览器向跨域资源服务器放出XMLHttpRequest请求,克服了AJAX只能同源使用的限制
CORS通信是浏览器自动完成的,不需要用户参与。CORS通信和同源的AJAX通信没有差别,代码完全一样,实
现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以通信
Access-Control-Allow-Origin:*
(1) 为什么会有跨域的问题
浏览器安全的基石是:同源策略。什么是同源策略,简言之就是:请求的
协议相同 + 域名相同 + 端口号相同,只有在这三种情况都相同的情况下,才能
被称为同源策略。特别是在前后端分离开发的条件下,几乎跨域是一定会遇到的问题。
(2)CORS请求分成两类:简单请求和非简单请求
只有满足一下两大请求就属于简单请求:
(1)请求方法是以下三种方法之一:Head,get,post
(2) Http的头消息不能超出一下几种字段:
Content-Type:只限于三个值:application/x-www-form-urlencoded,(一般请求默认的方法)
multipart/form-data,text/plain
除此之外:凡是不满足的都是非简单请求
(3)CORS请求流程
1, 对于简单请求,浏览器直接发出CORS请求,并且在请求当前头信息中添加一个origin字段。origin其实
就是(协议+域名+端口号),服务器根据这个值决定是否同意这次请求。
2, 对于非简单请求,比如请求方法是put或者delete,或者Content-Type字段类型是application/json,
在正是请求之前会,服务器发现你是一个非简单请求,就会自动发出一个预检请求,预检请求的方法是
OPTIONS,表示咨询。如果如服务器对预检请求的结果是允许跨域请求,就会第二次发出请求跨域请求。一旦服
务器通过了预检请求,以后的每一次CORS请求都是简单请求了。
(4)CORS默认请求不会发送Cookie和HTTP认证信息的。如果要把Cookie发送到服务器,需要知道服务器同意:
Access-Control-Allow-Credentials:true
前端需要设置: widthCredentials = true
(5)CORS与JSONP的比较
CORS与JSON的目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSON的优势在与支持老式浏览器,
可以向布置COR的网站请求数据
注意:我们在使用POST方式是,JQuery,Axios等封装的Ajax库,都采用默认的
Content-Type:application/x-www-form-urlencoded,不会触发预请求
举例:处理POST预请求方法
前端发出请求,触发预请求
var data = { name: 'BruceLee', password: '123456' };
$.ajax({
url: "http://localhost:3000",
type: "post",
data: JSON.stringify(data),
contentType: 'application/json;charset=utf-8',
success: function (result) {
console.log(result);
},
error: function (msg) {
console.log(msg);
}
})
服务器端要增加对OPTIONS得请求,比如node.js
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end("{name: 'BruceLee', password: '123456'}");
}
if (request.method === 'POST') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end( JSON.stringify({state: true}) );
}
if (request.method === 'OPTIONS') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*', // 设置 optins 方法允许所有服务器访问
'Access-Control-Allow-Methods': '*', // 允许访问路径 '/' POST等所有方法
'Access-Control-Allow-Headers': 'Content-Type', // 允许类 Content-Type 头部
});
}
}
response.end('false');
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
总结: 使用CORS跨域资源共享,是需要分成预请求和非预请求处理的。
(1)非预请求:只需要在服务器端简单的数字:
'Access-Control-Allow-Origin': '*'
(2)预请求,在服务器内,至少需要设置三个响应首部字段:
(3) 前端使用Content-Type:application/json的时候,必须注意,这是要发生预请求的,后端需要相对于的处理一下OPTIONS方法
4, JSONP跨域
根据同源策略的限制,在端口号,域名,协议其中有一个或者多个不同的时候,所发出来的请求都是跨域请求,受到了跨域限制。但是也有例外:比如:
(1) JSONP使用也很广泛,在我之前做的电信项目里面,因为和多个CP方合作。对方的后端服务器不支持CORS 方法,所以很多跨域请求都是通过JSONP实现的,再比如QQ,豆瓣,也是基于这种方式实现的。
(2)JSONP实现原理
1,利用sciprt加载远程js脚步 script src='url'
2,前端页面需要声明一个函数,函数名称需要和后端返回的字段从名称一致
3,script标签加载返回得到字符串,并被解析为可执行的javascript代码,调用前端声明的函数
举例:
<!DOCTYPE html>
<html lang="zh-CN">
<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>JSONP跨域请求</title>
</head>
<body>
<script>
function jsonCallback(data) {
console.log(data);
}
</script>
<script src="https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg"></script>
</body>
</html>
服务器端出来JONSP请求:nodejs方式
const http = require('http');
var data = { name: 'BruceLee', password: '123456' };
const server = http.createServer((request, response) => {
if (request.url === '/') {
response.writeHead(200, {
'Content-Type': 'application/json;charset=utf-8'
});
// 返回一段 JavaScript 代码
response.end( "jsonpCallback(" + JSON.stringify(data) + ")" );
}
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
注意: JSONP只支持前端发出的Get请求,无法实现上传数据等操作
反观:CORS更加强大