精华内容
下载资源
问答
  • APP交叉事件测试
    千次阅读
    2015-11-19 19:49:48

    APP交叉事件测试

    针对智能终端应用的服务等级划分方式及实时特性所提出的测试方法。交叉测试又叫事件或冲突测试,是指一个功能正在执行过程中,同时另外一个事件或操作对该过程进行干扰的测试。如;App在前/后台运行状态时与来电、文件下载、音乐收听等关键运用的交互情况测试等。交叉事件测试非常重要,能发现很多应用中潜在的性能问题。

    1) 多个App同时运行是否影响正常功能

    2)App运行时前/后台切换是否影响正常功能

    3)App运行时拨打/接听电话

    4)App运行时发送/接收信息

    5)App运行时发送/收取邮件

    6)App运行时切换网络(2G、3G、wifi)

    7)App运行时浏览网络

    8)App运行时使用蓝牙传送/接收数据

    9)App运行时使用相机、计算器等手机自带设备

    更多相关内容
  • vue 表单验证按钮事件交由父组件触发,不直接再子组件上操作的方法 子组件: //内容部分 <Form ref=formCustom :model=formCustom :rules=ruleCustom :label-width=80> <Input type=text v-model=...
  • 交案件中关于第三者的认定分析
  • 房期间业主维权突发事件应急预案..doc
  • 房期间业主维权突发事件应急预案.rar
  • 房期间业主维权突发事件应急预案.doc
  • 房期间业主维权突发事件应急预案.pdf
  • 房期间业主维权突发事件应急预案整理.pdf
  • 这是一套扁平化风格制作的,医院护理接班制度培训...三、接班的护理缺陷、不良事件 四、手术病人的交接流程 五、患者转入、转出交接 ... 关键词:医院培训PPT下载,医院护理接班制度培训PPT免费下载,.PPTX格式;
  • 房期间业主维权突发事件应急预案实用.pdf
  • 房期间业主维权突发事件应急处置预案.doc
  • 房期间业主维权突发事件应急预案(DOC).pdf
  • 房期间业主维权突发事件应急预案.-4页.pdf
  • 基于文本数据挖掘的复式分道岔设备故障事件分析.pdf
  • 参考资料-民事裁定书(未二审案件受理费按撤回上诉处理用).zip
  • 为实现城市交通网络中针对突发事件的快速出警与处理,利用Dijkstra算法和指派问题给出了警务平台的设置与调度模型。通过对某市市区有关数据统计结果进行主成分分析,提出了该市区现有平台设置的不合理之处和改进方案...
  • 机械行业事件点评:160列复兴号动车组招标启动,助力轨行业景气提升.pdf
  • 事件响应,根据在绘图区域绘制的线条求出交点,交点以浅绿色圆点显示。 3)刷新按钮;清屏绘图区域,以便重新再绘; 4)绘图区域文本框;提示用户; 5)列表框;按X轴坐标大小排序,依次显示交点坐标; 6).绘图区域...
  • 一、什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为因为它经常被用于类似如下的方式来实现 while (queue.waitForMessage()) { queue.processNextMessage(); } ...

    深入理解JavaScript的事件循环(Event Loop)

     

    一、什么是事件循环

    JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为因为它经常被用于类似如下的方式来实现

    while (queue.waitForMessage()) {
      queue.processNextMessage();
    }
    

    如果当前没有任何消息queue.waitForMessage 会等待同步消息到达

    我们可以把它当成一种程序结构的模型,处理的方案。更详细的描述可以查看 这篇文章

    而JS的运行环境主要有两个:浏览器Node

    在两个环境下的Event Loop实现是不一样的,在浏览器中基于 规范 来实现,不同浏览器可能有小小区别。在Node中基于 libuv 这个库来实现

    JS是单线程执行的,而基于事件循环模型,形成了基本没有阻塞(除了alert或同步XHR等操作)的状态

    二、Macrotask 与 Microtask

    根据 规范,每个线程都有一个事件循环(Event Loop),在浏览器中除了主要的页面执行线程 外,Web worker是在一个新的线程中运行的,所以可以将其独立看待。

    每个事件循环有至少一个任务队列(Task Queue,也可以称作Macrotask宏任务),各个任务队列中放置着不同来源(或者不同分类)的任务,可以让浏览器根据自己的实现来进行优先级排序

    以及一个微任务队列(Microtask Queue),主要用于处理一些状态的改变,UI渲染工作之前的一些必要操作(可以防止多次无意义的UI渲染)

    主线程的代码执行时,会将执行程序置入执行栈(Stack)中,执行完毕后出栈,另外有个堆空间(Heap),主要用于存储对象及一些非结构化的数据

     

     

    一开始

    宏任务与微任务队列里的任务随着:任务进栈、出栈、任务出队、进队之间交替着进行

    从macrotask队列中取出一个任务处理,处理完成之后(此时执行栈应该是空的),从microtask队列中一个个按顺序取出所有任务进行处理,处理完成之后进入UI渲染后续工作

    需要注意的是:microtask并不是在macrotask完成之后才会触发,在回调函数之后,只要执行栈是空的,就会执行microtask。也就是说,macrotask执行期间,执行栈可能是空的(比如在冒泡事件的处理时)

    然后循环继续

    常见的macrotask有:

    • run <script>(同步的代码执行)
    • setTimeout
    • setInterval
    • setImmediate (Node环境中)
    • requestAnimationFrame
    • I/O
    • UI rendering

    常见的microtask有:

    • process.nextTick (Node环境中)
    • Promise callback
    • Object.observe (基本上已经废弃)
    • MutationObserver

    macrotask种类很多,还有 dispatch event事件派发等

    run <script>这个可能看起来比较奇怪,可以把它看成一段代码(针对单个<script>标签)的同步顺序执行,主要用来描述执行程序的第一步执行

    dispatch event主要用来描述事件触发之后的执行任务,比如用户点击一个按钮,触发的onClick回调函数。需要注意的是,事件的触发是同步的,这在下文有例子说明

    注:

    当然,也可认为 run <script>不属于macrotask,毕竟规范也没有这样的说明,也可以将其视为主线程上的同步任务,不在主线程上的其他部分为异步任务

    三、在浏览器中的实现

    先来看看这段蛮复杂的代码,思考一下会输出什么

                console.log('start');
    
                var intervalA = setInterval(() => {
                    console.log('intervalA');
                }, 0);
    
                setTimeout(() => {
                    console.log('timeout');
    
                    clearInterval(intervalA);
                }, 0);
    
                var intervalB = setInterval(() => {
                    console.log('intervalB');
                }, 0);
    
                var intervalC = setInterval(() => {
                    console.log('intervalC');
                }, 0);
    
                new Promise((resolve, reject) => {
                    console.log('promise');
    
                    for (var i = 0; i < 10000; ++i) {
                        i === 9999 && resolve();
                    }
    
                    console.log('promise after for-loop');
                }).then(() => {
                    console.log('promise1');
                }).then(() => {
                    console.log('promise2');
    
                    clearInterval(intervalB);
                });
    
                new Promise((resolve, reject) => {
                    setTimeout(() => {
                        console.log('promise in timeout');
                        resolve();
                    });
    
                    console.log('promise after timeout');
                }).then(() => {
                    console.log('promise4');
                }).then(() => {
                    console.log('promise5');
    
                    clearInterval(intervalC);
                });
    
                Promise.resolve().then(() => {
                    console.log('promise3');
                });
    
                console.log('end');
    

    上述代码结合了常规执行代码,setTimeout,setInterval,Promise

    答案为

     

     

    在解释为什么之前,先看一个更简单的例子

                console.log('start');
    
                setTimeout(() => {
                    console.log('timeout');
                }, 0);
    
                Promise.resolve().then(() => {
                    console.log('promise');
                });
    
                console.log('end');
    

    大概的步骤,文字有点多

    1. 运行时(runtime)识别到log方法为一般的函数方法,将其入栈,然后执行输出 start 再出栈

    2. 识别到setTimeout为特殊的异步方法(macrotask),将其交由其他内核模块处理,setTimeout的匿名回调函数被放入macrotask队列中,并设置了一个 0ms的立即执行标识(提供后续模块的检查)

    3. 识别到Promise的resolve方法为一般的方法,将其入栈,然后执行 再出栈

    4. 识别到then为Promise的异步方法(microtask),将其交由其他内核模块处理,匿名回调函数被放入microtask队列中

    5. 识别到log方法为一般的函数方法,将其入栈,然后执行输出 end 再出栈

    6. 主线程执行完毕,栈为空,随即从microtask队列中取出队首的项,

    这里队首为匿名函数,匿名函数里面有 console的log方法,也将其入栈(如果执行过程中识别到特殊的方法,就在这时交给其他模块处理到对应队列尾部),

    输出 promise后出栈,并将这一项从队列中移除

    7. 继续检查microtask队列,当前队列为空,则将当前macrotask出队,进入下一步(如果不为空,就继续取下一个microtask执行)

    8.检查是否需要进行UI重新渲染等,进行渲染...

    9. 进入下一轮事件循环,检查macrotask队列,取出一项进行处理

    所以最终的结果是

     

     

    再看上面那个例子,对比起来只是代码多了点,混入了setInterval,多个setTimeout与promise的函数部分,按照上面的思路,应该不难理解

    需要注意的三点:

    1. clearInterval(intervalA); 运行的时候,实际上已经执行了 intervalA 的macrotask了
    2. promise函数内部是同步处理的,不会放到队列中,放入队列中的是它的then或catch回调
    3. promise的then返回的还是promise,所以在输出promise4后,继续检测到后续的then方法,马上放到microtask队列尾部,再继续取出执行,马上输出promise5;

    而输出promise1之后,为什么没有马上输出promise2呢?因为此时promise1所在任务之后是promise3的任务,1和3在promise函数内部返回后就添加至队列中,2在1执行之后才添加

    再来看个例子,就有点微妙了

        <script>
            console.log('start');
    
            setTimeout(() => {
                console.log('timeout1');
            }, 0);
    
            Promise.resolve().then(() => {
                console.log('promise1');
            });
        </script>
        <script>
            setTimeout(() => {
                console.log('timeout2');
            }, 0);
    
            requestAnimationFrame(() => {
                console.log('requestAnimationFrame');
            });
    
            Promise.resolve().then(() => {
                console.log('promise2');
            });
    
            console.log('end');
        </script>
    

    输出结果

     

     

    requestAnimationFrame是在setTimeout之前执行的,start之后并不是直接输出end,也许这两个<script>标签被独立处理了

    来看一个关于DOM操作的例子,Tasks, microtasks, queues and schedules

    <style type="text/css">
        .outer {
            width: 100px;
            background: #eee;
            height: 100px;
            margin-left: 300px;
            margin-top: 150px;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    
        .inner {
            width: 50px;
            height: 50px;
            background: #ddd;
        }
    </style>
    
    <script>
            var outer = document.querySelector('.outer'),
                inner = document.querySelector('.inner'),
                clickTimes = 0;
    
            new MutationObserver(() => {
                console.log('mutate');
            }).observe(outer, {
                attributes: true
            });
    
            function onClick() {
                console.log('click');
    
                setTimeout(() => {
                    console.log('timeout');
                }, 0);
    
                Promise.resolve().then(() => {
                    console.log('promise');
                });
    
                outer.setAttribute('data-click', clickTimes++);
            }
    
            inner.addEventListener('click', onClick);
            outer.addEventListener('click', onClick);
    
            // inner.click();
    
            // console.log('done');
        </script>

     

     

    点击内部的inner块,会输出什么呢?

     

     

    MutationObserver优先级比promise高,虽然在一开始就被定义,但实际上是触发之后才会被添加到microtask队列中,所以先输出了promise

    两个timeout回调都在最后才触发,因为click事件冒泡了,事件派发这个macrotask任务包括了前后两个onClick回调,两个回调函数都执行完之后,才会执行接下来的 setTimeout任务

    期间第一个onClick回调完成后执行栈为空,就马上接着执行microtask队列中的任务

    如果把代码的注释去掉,使用代码自动 click(),思考一下,会输出什么?

     

     

    可以看到,事件处理是同步的,done在连续输出两个click之后才输出

    而mutate只有一个,是因为当前执行第二个onClick回调的时候,microtask队列中已经有一个MutationObserver,它是第一个回调的,因为事件同步的原因没有被及时执行。浏览器会对MutationObserver进行优化,不会重复添加监听回调

    四、在Node中的实现

    在Node环境中,macrotask部分主要多了setImmediate,microtask部分主要多了process.nextTick,而这个nextTick是独立出来自成队列的,优先级高于其他microtask

    不过事件循环的的实现就不太一样了,可以参考 Node事件文档 libuv事件文档

    Node中的事件循环有6个阶段

    • timers:执行setTimeout() 和 setInterval()中到期的callback
    • I/O callbacks:上一轮循环中有少数的I/Ocallback会被延迟到这一轮的这一阶段执行
    • idle, prepare:仅内部使用
    • poll:最为重要的阶段,执行I/O callback,在适当的条件下会阻塞在这个阶段
    • check:执行setImmediate的callback
    • close callbacks:执行close事件的callback,例如socket.on("close",func)

     

     

    每一轮事件循环都会经过六个阶段,在每个阶段后,都会执行microtask

     

     

    比较特殊的是在poll阶段,执行程序同步执行poll队列里的回调,直到队列为空或执行的回调达到系统上限

    接下来再检查有无预设的setImmediate,如果有就转入check阶段,没有就先查询最近的timer的距离,以其作为poll阶段的阻塞时间,如果timer队列是空的,它就一直阻塞下去

    而nextTick并不在这些阶段中执行,它在每个阶段之后都会执行

    看一个例子

    setTimeout(() => console.log(1));
    
    setImmediate(() => console.log(2));
    
    process.nextTick(() => console.log(3));
    
    Promise.resolve().then(() => console.log(4));
    
    console.log(5); 
    

    根据以上知识,应该很快就能知道输出结果是 5 3 4 1 2

    修改一下

    process.nextTick(() => console.log(1));
    
    Promise.resolve().then(() => console.log(2));
    
    process.nextTick(() => console.log(3));
    
    Promise.resolve().then(() => {
        process.nextTick(() => console.log(0));
        console.log(4);
    });
    

    输出为 1 3 2 4 0,因为nextTick队列优先级高于同一轮事件循环中其他microtask队列

    修改一下

    process.nextTick(() => console.log(1));
    
    console.log(0);
    
    setTimeout(()=> {
        console.log('timer1');
    
        Promise.resolve().then(() => {
            console.log('promise1');
        });
    }, 0);
    
    process.nextTick(() => console.log(2));
    
    setTimeout(()=> {
        console.log('timer2');
    
        process.nextTick(() => console.log(3));
    
        Promise.resolve().then(() => {
            console.log('promise2');
        });
    }, 0);
    

    输出为

     

     

    与在浏览器中不同,这里promise1并不是在timer1之后输出,因为在setTimeout执行的时候是出于timer阶段,会先一并处理timer回调

    setTimeout是优先于setImmediate的,但接下来这个例子却不一定是先执行setTimeout的回调

    setTimeout(() => {
        console.log('timeout');
    }, 0);
    
    setImmediate(() => {
        console.log('immediate');
    });
    

     

     

    因为在Node中识别不了0ms的setTimeout,至少也得1ms.

    所以,如果在进入该轮事件循环的时候,耗时不到1ms,则setTimeout会被跳过,进入check阶段执行setImmediate回调,先输出 immediate

    如果超过1ms,timer阶段中就可以马上处理这个setTimeout回调,先输出 timeout

    修改一下代码,读取一个文件让事件循环进入IO文件读取的poll阶段

    let fs = require('fs');
    
        fs.readFile('./event.html', () => {
            setTimeout(() => {
                console.log('timeout');
            }, 0);
    
            setImmediate(() => {
                console.log('immediate');
            });
        });
    

    这么一来,输出结果肯定就是 先 immediate 后 timeout

    五、用好事件循环

    知道JS的事件循环是怎么样的了,就需要知道怎么才能把它用好

    1. 在microtask中不要放置复杂的处理程序,防止阻塞UI的渲染

    2. 可以使用process.nextTick处理一些比较紧急的事情

    3. 可以在setTimeout回调中处理上轮事件循环中UI渲染的结果

    4. 注意不要滥用setInterval和setTimeout,它们并不是可以保证能够按时处理的,setInterval甚至还会出现丢帧的情况,可考虑使用 requestAnimationFrame

    5. 一些可能会影响到UI的异步操作,可放在promise回调中处理,防止多一轮事件循环导致重复执行UI的渲染

    6. 在Node中使用immediate来可能会得到更多的保证

    7. 不要纠结

    展开全文
  • (已降重)三、群体性欠薪事件发生的原因(降到2400字知网15%以下晚上10点)2.zip
  • React的事件绑定,是通过在react元素上添加事件属性,且事件属性名必须采用驼峰命名的方式,如onClick等。 import React from 'react' const Test = () => { const handleClick = () => { console.log('...

    React的事件绑定,是通过在react元素上添加事件属性,且事件属性名必须采用驼峰命名的方式,如onClick等。

    import React from 'react'
    
    const Test = () => {
        const handleClick = () => {
            console.log('点击我')
        }
        return (
            <div onClick={this.handleClick.bind(this)}>点我</div>
        )
    }
    
    export default Test

    那么写<div onClick={this.handleClick.bind(this)}>点我</div>这样的一个原理是什么呢?

    其实react并不是将click事件绑定到了div的真实DOM上,而是在document处监听了所有的事件,当事件发生并且冒泡到document处的时候,React将事件内容封装并交由真正的处理函数运行。这样的方式不仅仅减少了内存的消耗,还能在组件挂在销毁时统一订阅和移除事件。

    另外冒泡到document上的事件也不是原生的浏览器事件,而是由react自己实现的合成事件(SyntheticEvent).因此我们如果不想要是事件冒泡的话调用event.stopProppagation()方法是无效的。而应该调用event.preventDefault().

    就这样。。。 

    展开全文
  • 结果表明:长江口历史上多次规模不同的海进海退及北岸砂坝并陆事件,长江口岸线往复移动,形成了长江口北岸全新世沉积物黏性土或薄层黏土与粉、细砂互层、多韵律沉积特征;细观上海陆互相沉积土层黏土与粉砂相互...
  • 本文以基于扫描线算法求线段的交点,首先设有一条扫描线l,从高于所有线段的位置起,自上而下地扫描整个平面,与当前扫描线相交的线段构成一个扫描线状态结构,在扫描线从上个事件点移到下个事件点时,要根据事件点...
  • 对于事件可以通过ViewGroup下发到它的子View并由子View进行处理,而ViewGroup本身也能够对事件做出处理。下面就来详细分析一下ViewGroup对时间的分发处理。 MotionEvent  当手指接触到屏幕以后,所产生的一系列的...
  • 什么是跨域?跨域解决方法

    万次阅读 多人点赞 2018-12-14 19:22:02
    一、为什么会出现跨域问题 出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建...

    一、为什么会出现跨域问题

    出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

    二、什么是跨域

    当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

    当前页面url被请求页面url是否跨域原因
    http://www.test.com/http://www.test.com/index.html同源(协议、域名、端口号相同)
    http://www.test.com/https://www.test.com/index.html跨域协议不同(http/https)
    http://www.test.com/http://www.baidu.com/跨域主域名不同(test/baidu)
    http://www.test.com/http://blog.test.com/跨域子域名不同(www/blog)
    http://www.test.com:8080/http://www.test.com:7001/跨域端口号不同(8080/7001)

    三、非同源限制

    【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB

    【2】无法接触非同源网页的 DOM

    【3】无法向非同源地址发送 AJAX 请求

    四、跨域解决方法

    【1】设置document.domain解决无法读取非同源网页的 Cookie问题

    因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)

    // 两个页面都设置
    document.domain = 'test.com';

    【2】跨文档通信 API:window.postMessage()

    调用postMessage方法实现父窗口http://test1.com向子窗口http://test2.com发消息(子窗口同样可以通过该方法发送消息给父窗口)

    它可用于解决以下方面的问题:

    • 页面和其打开的新窗口的数据传递
    • 多窗口之间消息传递
    • 页面与嵌套的iframe消息传递
    • 上面三个场景的跨域数据传递
    // 父窗口打开一个子窗口
    var openWindow = window.open('http://test2.com', 'title');
    
    // 父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
    openWindow.postMessage('Nice to meet you!', 'http://test2.com');

    调用message事件,监听对方发送的消息

    // 监听 message 消息
    window.addEventListener('message', function (e) {
      console.log(e.source); // e.source 发送消息的窗口
      console.log(e.origin); // e.origin 消息发向的网址
      console.log(e.data);   // e.data   发送的消息
    },false);

    【3】JSONP

    JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

    核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

    ①原生实现:

    <script src="http://test.com/data.php?callback=dosomething"></script>
    // 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
    
    // 处理服务器返回回调函数的数据
    <script type="text/javascript">
        function dosomething(res){
            // 处理获得的数据
            console.log(res.data)
        }
    </script>
    

    ② jQuery ajax:

    $.ajax({
        url: 'http://www.test.com:8080/login',
        type: 'get',
        dataType: 'jsonp',  // 请求方式为jsonp
        jsonpCallback: "handleCallback",    // 自定义回调函数名
        data: {}
    });

    ③ Vue.js

    this.$http.jsonp('http://www.domain2.com:8080/login', {
        params: {},
        jsonp: 'handleCallback'
    }).then((res) => {
        console.log(res); 
    })

    【4】CORS

    CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

    1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin

    2、带cookie跨域请求:前后端都需要进行设置

    【前端设置】根据xhr.withCredentials字段判断是否带有cookie

    ①原生ajax

    var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
    
    // 前端设置是否带cookie
    xhr.withCredentials = true;
    
    xhr.open('post', 'http://www.domain2.com:8080/login', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('user=admin');
    
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    };

    ② jQuery ajax 

    $.ajax({
       url: 'http://www.test.com:8080/login',
       type: 'get',
       data: {},
       xhrFields: {
           withCredentials: true    // 前端设置是否带cookie
       },
       crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
    });
    
    
        

    ③vue-resource

    Vue.http.options.credentials = true

    ④ axios 

    axios.defaults.withCredentials = true

    【服务端设置】

    服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

    ① Java后台

    /*
     * 导入包:import javax.servlet.http.HttpServletResponse;
     * 接口参数中定义:HttpServletResponse response
     */
    
    // 允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'
    response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); 
    
    // 允许前端带认证cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名,否则浏览器会提示
    response.setHeader("Access-Control-Allow-Credentials", "true"); 
    
    // 提示OPTIONS预检时,后端需要设置的两个常用自定义头
    response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With");

    ② Nodejs后台

    var http = require('http');
    var server = http.createServer();
    var qs = require('querystring');
    
    server.on('request', function(req, res) {
        var postData = '';
    
        // 数据块接收中
        req.addListener('data', function(chunk) {
            postData += chunk;
        });
    
        // 数据接收完毕
        req.addListener('end', function() {
            postData = qs.parse(postData);
    
            // 跨域后台设置
            res.writeHead(200, {
                'Access-Control-Allow-Credentials': 'true',     // 后端允许发送Cookie
                'Access-Control-Allow-Origin': 'http://www.domain1.com',    // 允许访问的域(协议+域名+端口)
                /* 
                 * 此处设置的cookie还是domain2的而非domain1,因为后端也不能跨域写cookie(nginx反向代理可以实现),
                 * 但只要domain2中写入一次cookie认证,后面的跨域接口都能从domain2中获取cookie,从而实现所有的接口都能跨域访问
                 */
                'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'  // HttpOnly的作用是让js无法读取cookie
            });
    
            res.write(JSON.stringify(postData));
            res.end();
        });
    });
    
    server.listen('8080');
    console.log('Server is running at port 8080...');

    ③ PHP后台

    <?php
     header("Access-Control-Allow-Origin:*");
    

    ④ Apache需要使用mod_headers模块来激活HTTP头的设置,它默认是激活的。你只需要在Apache配置文件的<Directory>, <Location>, <Files>或<VirtualHost>的配置里加入以下内容即可

    Header set Access-Control-Allow-Origin *

    【5】webpack本地代理

     å¾ç

    在webpack.config.js中利用 WebpackDevServer 配置本地代理,详情配置查看devServer

    如下简单配置案例,这样 `http://localhost:8080/api/getUser.php` 的请求就是后端的接口 `http://192.168.25.20:8088/getUser.php`

        devServer: {
            port: 8080,
            proxy: {
                "/api": {
                  target: "http://192.168.25.20:8088" // 后端接口
                }
            }
        }

    【6】websocket

    Websocket 是 HTML5 的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案。WebSocket 和 HTTP 都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 服务器与 客户端都能主动向对方发送或接收数据。同时,WebSocket 在建立连接时需要借助 HTTP 协议,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了。

    【7】Nginx反向代理

    Nginx 实现原理类似于 Node 中间件代理,需要你搭建一个中转 nginx 服务器,用于转发请求。

    使用 nginx 反向代理实现跨域,是最简单的跨域方式。只需要修改 nginx 的配置即可解决跨域问题,支持所有浏览器,支持 session,不需要修改任何代码,并且不会影响服务器性能。

    我们只需要配置nginx,在一个服务器上配置多个前缀来转发http/https请求到多个真实的服务器即可。这样,这个服务器上所有url都是相同的域 名、协议和端口。因此,对于浏览器来说,这些url都是同源的,没有跨域限制。而实际上,这些url实际上由物理服务器提供服务。这些服务器内的 javascript可以跨域调用所有这些服务器上的url。

    先下载nginx,然后将 nginx 目录下的 nginx.conf 修改如下:

    server {
    
        #nginx监听所有localhost:8080端口收到的请求
    	listen       8080;
    	server_name  localhost;
    
    	# Load configuration files for the default server block.
    	include /etc/nginx/default.d/*.conf;
    
        #localhost:8080 会被转发到这里
    	#同时, 后端程序会接收到 "192.168.25.20:8088"这样的请求url
    	location / {
    		proxy_pass http://192.168.25.20:8088;
    	}
    
    	#localhost:8080/api/ 会被转发到这里
        #同时, 后端程序会接收到 "192.168.25.20:9000/api/"这样的请求url
    	location /api/ {
    		proxy_pass http://192.168.25.20:9000;
    	}
    
    	error_page 404 /404.html;
    		location = /40x.html {
    	}
    
    	error_page 500 502 503 504 /50x.html;
    		location = /50x.html {
    	}
    }

    文章每周持续更新,可以微信搜索「 前端大集锦 」第一时间阅读,回复【视频】【书籍】领取200G视频资料和30本PDF书籍资料

    展开全文
  • 滇黔桂盆地及其邻区在晚二叠世长兴晚期发生快速海侵,导致了第1幕淹没事件,研究区内的连陆台地大...这两幕淹没不整合面合称二叠系与三叠系之的淹没不整合面,它们是三级层序SQ26的底界面,具有明显的穿时性;凝缩段
  • 4S店提车,PDI的检测是个什么鬼?

    千次阅读 2021-01-17 02:12:03
    关注西安奔驰事件的人都会发现,其中提到了汽车的PDI检测,那么到底什么是PDI检测呢?PDI全拼为Pre Delivery Inspection,说的明白点就是4S点将车辆到客户手中之前,要对车辆进行全面检查,并调整到正常的状态。...
  • 事件和委托在编程中经常配合使用,这个小例子将会教你当事件被激活时,如何在类外部相应事件处理程序,
  • 养老保险交费需要到生日当月,生日当月办理退休手续,次月就可以领取退休证和退休工资卡,并且可以领取养老金了,当然就不用再养老保险了。例如:7月份到达退休年龄,7月份应该缴纳养老保险费用,个人参保并符合...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 137,408
精华内容 54,963
关键字:

交事件是什么