• home > webfront > SGML > html >

    http请求发生了两次:options请求分析,移动端开发样式重置

    Author:lmk Date:

    一个接口一个ajax,为什么会发生两次为什么发生两次请求,如何产生options请求?简单请求与复杂请求区别?Access-Control-Max-Age来设置什么?移动端开发样式重置及meta标签

    http的请求方式

    包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE和CONNECT等八种请求方式。其中,get与post只是我们常用的请求方式。

    options请求

    OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。

    用白话说就是:在发生正式的请求之前,先进行一次预检请求。看服务端返回一些信息,浏览器拿到之后,看后台是否允许进行访问。

    出于安全考虑,并不是所有域名访问后端服务都可以。其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求)

    options请求有什么作用

    出于安全考虑,并不是所有域名访问后端服务都可以。其实在正式跨域之前,浏览器会根据需要发起一次预检(也就是option请求),用来让服务端返回允许的方法(如get、post),被跨域访问的Origin(来源或者域),还有是否需要Credentials(认证信息)等。

    • 第一次是浏览器使用OPTIONS方法发起一个预检请求,预检请求获知服务器是否允许该跨域请求:如果允许,才发起第二次真实的请求;如果不允许,则拦截第二次请求。

    • 第二次才是真正的异步请求,传输数据

    官方将头部带自定义信息的请求方式称为带预检(preflighted)的跨域请求。在实际调用接口之前,会首先发出一个options请求,检测服务端是否支持真实的请求进行跨域的请求。真实请求在options请求中,通过request-header将 Access-Control-Request-HeadersAccess-Control-Request-Method发送给后台,另外浏览器会自行加上一个Origin请求地址。服务端在接收到预检请求后,根据资源权限配置,在response-header头部加入access-control-allow-headers(允许跨域请求的请求头)、access-control-allow-methods(允许跨域请求的请求方式)、access-control-allow-origin(允许跨域请求的域)。

    另外,服务端还可以通过Access-Control-Max-Age来设置一定时间内无须再进行预检请求,直接用之前的预检请求的协商结果即可

    Access-Control-Max-Age用来指定本次预检请求的有效期,单位为秒,,在此期间不用发出另一条预检请求

    • resp.addHeader("Access-Control-Max-Age", "0"),表示每次异步请求都发起预检请求,也就是说,发送两次请求。

    • resp.addHeader("Access-Control-Max-Age", "1800"),表示隔30分钟才发起预检请求。也就是说,发送两次请求

    浏览器再根据服务端返回的信息,进行决定是否再进行真实的跨域请求。这个过程对于用户来说,也是透明的。

    另外在HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allow-Credentials: true的,浏览器都会忽略此次响应

    总结:只要是带自定义header的跨域请求,在发送真实请求前都会先发送OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。所以复杂请求肯定会两次请求服务端。

    如何产生options请求:

    简单请求与复杂请求

    1. 简单请求(simple request),简单请求浏览器不会预检,同时满足下列三大条件,就属于简单请求,

      1. 请求方式只能是:GET、POST、HEAD

      2. HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID

      3. Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain

    2. 非简单请求(not-simple-request)而非简单请求会预检。

    产生options请求的原因

    1. 发生了跨域。跨域的复杂请求(在前端发起Ajax请求后,先与查询服务器 CORS 配置,查看是否允许请求)

    2. 产生了复杂请求。复杂请求对应的就是简单请求。简单请求的定义是:

      1. 请求中有自定义HTTP头部。所谓的自定义头部,在实际的项目里,我们经常会遇到需要在header头部加上一些token或者其他的用户信息,用来做用户信息的校验。

    options请求如何避免

    其实通过以上的分析,我们能得出以下解决方案:

    1:使用代理,避开跨域。

    2:将复杂跨域请求更改为简单跨域请求。

    3:不使用带自定义配置的header头部。


    移动端开发样式重置及meta标签

    1 -webkit-tap-highlight-color-webkit-tap-highlight-color:rgba(0,0,0,0); 透明度设置为0,去掉点击链接和文本框对象时默认的灰色半透明

    1.-webkit-tap-highlight-color

    -webkit-tap-highlight-color:rgba(0,0,0,0);//透明度设置为0,去掉点击链接和文本框对象时默认的灰色半透明覆盖层(iOS)或者虚框(Android)

    -webkit-tap-highlight-color:rgba(255,0,0,0.5);   //利用此属性,设置touch时链接区域高亮为50%的透明红,只在ios上起作用。android上只要使用了此属性就表现为边框。在body上加此属性,这样就保证body的点击区域效果一致了

    2.outline:none

    (1)在pc端为a标签定义这个样式的目的是为了取消ie浏览器下点击a标签时出现的虚线。ie7及以下浏览器还不识别此属性,需要在a标签上添加hidefocus="true"

    (2)input,textarea{outline:none}  取消chrome下默认的文本框聚焦样式

    (3)在移动端是不起作用的,想要去除文本框的默认样式可以使用-webkit-appearance,聚焦时候默认样式的取消是-webkit-tap-highlight-color。看到一些移动端reset文件加了此属性,其实是多余。

    3.-webkit-appearance

    -webkit-appearance: none;//消除输入框和按钮的原生外观,在iOS上加上这个属性才能给按钮和输入框自定义样式 

    不同type的input使用这个属性之后表现不一。text、button无样式,radio、checkbox直接消失

    4.-webkit-user-select

    -webkit-user-select: none; // 禁止页面文字选择 ,此属性不继承,一般加在body上规定整个body的文字都不会自动调整

    5.-webkit-text-size-adjust

    -webkit-text-size-adjust: none; //禁止文字自动调整大小(默认情况下旋转设备的时候文字大小会发生变化),此属性也不继承,一般加在body上规定整个body的文字都不会自动调整 

    6.-webkit-touch-callout

    -webkit-touch-callout:none; // 禁用长按页面时的弹出菜单(iOS下有效) ,img和a标签都要加

    7.-webkit-overflow-scrolling

    -webkit-overflow-scrolling:touch;// 局部滚动(仅iOS 5以上支持) 

    1、Meta 之 viewport

    说到移动平台meta标签,那就不得不说一下viewport了,那么什么是viewport呢?

    viewport即可视区域,对于桌面浏览器而言,viewport指的就是除去所有工具栏、状态栏、滚动条等等之后用于看网页的区域

    。对于传统WEB页面来说,980的宽度在iphone上显示是很正常的,也是满屏的,但对于webapp而言,可能就有点问题了,在iphone上我们的webapp在竖屏下通常宽度都是320,这时我们320页面在iphone上显示成啥效果呢?有人可能认为iPhone不是320的宽度莫,感觉应该是满屏的吧,事实呢?我们来看一下如下布局在iPhone上的显示情况

     在iPhone上显示如图:
    20131127215320_55442

    因此我们必须改变viewport,我们就有如下几种属性值可以设置:


    width: viewport 的宽度 (范围从 200 到 10,000 ,默认为 980 像素 )

    height: viewport 的高度 (范围从 223 到 10,000 )

    initial-scale: 初始的缩放比例 (范围从>0到 10 )

    minimum-scale: 允许用户缩放到的最小比例

    maximum-scale: 允许用户缩放到的最大比例

    user-scalable: 用户是否可以手动缩放


    对于这些属性,我们可以设置其中的一个或者多个,并不需要你同时都设置,iPhone 会根据你设置的属性自动推算其他属性值 ,而非直接采用默认值。


    如果你把initial-scale=1 ,那么 width 和 height在竖屏时自动为320*356 (不是320*480 因为地址栏等都占据空间 ),横屏时自动为 480*208。类似地 ,如果你仅仅设置了 width ,就会自动推算出initial-scale 以及height。例如你设置了 width=320 ,竖屏时 initial-scale 就是 1 ,横屏时则变成 1.5 了。 那么到底这些设置如何让 Safari 知道 ?其实很简单 ,就一个 meta ,形如 :

    设置了meat后我们页面将如此呈现了:

     20131127215334_30547

    好了,我们就可以按全屏来布局我们的页面了,不用再担心页面显示的很小了!


    2、Meta 之 format-detection

    你明明写的一串数字没加链接样式,而iPhone会自动把你这个文字加链接样式、并且点击这个数字还会自动拨号!想去掉这个拨号链接该如何操作呢?这时我们的meta又该大显神通了,代码如下:


    telephone=no就禁止了把数字转化为拨号链接!

    telephone=yes就开启了把数字转化为拨号链接,要开启转化功能,这个meta就不用写了,在默认是情况下就是开启!


    3、Meta 之 apple-mobile-web-app-capable


    这meta的作用就是删除默认的苹果工具栏和菜单栏。content有两个值”yes”和”no”,当我们需要显示工具栏和菜单栏时,这个行meta就不用加了,默认就是显示。


    加了该meta的情况

    20131127215346_16269

    4、Meta 之 apple-mobile-web-app-status-bar-style

    作用是控制状态栏显示样式
    status-bar-style:black

    20131127215357_23131

    status-bar-style:black-translucent

    20131127215410_84248




    转载本站文章《http请求发生了两次:options请求分析,移动端开发样式重置》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/SGML/htmlBase/2015_0718_138.html