如何处理前端js跨域问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何处理前端js跨域问题相关的知识,希望对你有一定的参考价值。
前端跨域的解决方法非常的多,简单的给你介绍一下吧。
iframe解决跨域,这种方法也比较常见
JSONP解决跨域,简单,易上手
postMessage解决跨域,使用了比较新H5 API,所以存在一定的兼容问题;
服务器代由访问,方法对前端影响不大,但是后台相对会麻烦很多。
希望对您有帮助吧~~
参考技术A自己搭一个小型服务器就可以了。
或者webstorm和brackets都有自己集成的小型服务器,能解决跨域问题。
还有一种方法,就是如果是chrome浏览器的话
这里加上“--allow-file-access-from-files”也可以解决跨域问题
这个问题看不懂的话,你可以在后盾找到详解,明白不⊙ω⊙
后端一次性传了10w条数据,前端该如何处理?—— 面试高频
前端处理后端传的10w条数据
1. 这道题在考什么?
- 对于性能优化的处理方案
- 对于前端渲染机制的了解
- 极端情况下的处理及知识领域的广度
2.先用 node.js 整个10w条数据
const http = require('http')
const PORT = 8000
const server = http.createServer((req, res) =>
res.writeHead(200,
//设置允许跨域的域名,也可设置*允许所有域名
'Access-Control-Allow-Origin': '*',
//跨域允许的请求方法,也可设置*允许所有方法
"Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS",
//允许的header类型
'Access-Control-Allow-Headers': 'Content-Type'
)
let list = [];
let num = 0;
for (let i = 0; i < 200; i++)
num++;
list.push(
src: '图片地址',
text: `这是第$num张图片`,
id: num
)
res.end(JSON.stringify(list))
)
server.listen(PORT, () =>
console.log('服务跑起来了!')
)
3. 基础代码环境
- index.html 代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img
width: 150px;
.flex
display: flex;
padding: 10px;
</style>
</head>
<body>
<div id="container">
</div>
<script src="./index.js"></script>
</body>
</html>
- index.js 代码如下
const getList = () =>
return new Promise((resolve, reject) =>
// 创建请求
let ajax = new XMLHttpRequest();
// 这里请求的是本地服务器
ajax.open('get', 'http://127.0.0.1:8000');
ajax.send();
ajax.onreadystatechange = function()
if(ajax.readyState == 4 && ajax.status == 200)
resolve(JSON.parse(ajax.responseText))
)
const container = document.getElementById("container")
4. 常规处理方案
const renderList = async () =>
console.time('列表时间')
const list = await getList();
list.forEach( item =>
const div = document.createElement('div')
div.className = 'flex'
div.innerHTML = `<img src="$item.src" /><span>$item.text</span>`
container.appendChild(div)
);
console.timeEnd('列表时间')
renderList()
- 这种方案就是简单粗暴的循环渲染
- 此方案耗时大概是 13s
- 这种做法当然是不可取的,等到天都黑了,用户可能会骂娘
5. 优化的第一种方式 —— 前端分页
const renderList = async () =>
console.time('列表时间')
const list = await getList();
const total = list.length;
const page = 0;
const limit = 200;
// 总页数
const totalPage = Math.ceil(total / limit); // Math.ceil 1.1 => 2
const render = (page) =>
if(page >= totalPage) return
setTimeout(() =>
for(let i = page * limit; i < page * limit + limit; i++)
const item = list[i];
const div = document.createElement('div')
div.className = 'flex'
div.innerHTML = `<img src="$item.src" /><span>$item.text</span>`
container.appendChild(div)
render(page + 1)
, 0)
render(page);
console.timeEnd('列表时间')
renderList()
- 思路是把十万条数据分成 10w / 200页,再加上setTimeout,每次渲染一页,速度得到了大幅度提升。
- 方案耗时:不到 1s 搞定
6. 再次优化
const renderList = async () =>
console.time('列表时间')
const list = await getList();
const total = list.length;
const page = 0;
const limit = 200;
// 总页数
const totalPage = Math.ceil(total / limit); // Math.ceil 1.1 => 2
const render = (page) =>
if(page >= totalPage) return
requestAnimationFrame(() =>
for(let i = page * limit; i < page * limit + limit; i++)
const item = list[i];
const div = document.createElement('div')
div.className = 'flex'
div.innerHTML = `<img src="$item.src" /><span>$item.text</span>`
container.appendChild(div)
render(page + 1)
)
render(page);
console.timeEnd('列表时间')
renderList()
- 使用 requestAnimationFrame 代替 setTimeout,减少了重排的次数,极大提高了性能
7. 极致优化(最佳方案)
const renderList = async () =>
console.time('列表时间')
const list = await getList();
const total = list.length;
const page = 0;
const limit = 200;
// 总页数
const totalPage = Math.ceil(total / limit); // Math.ceil 1.1 => 2
const render = (page) =>
if(page >= totalPage) return
requestAnimationFrame(() =>
const fragment = document.createDocumentFragment()
// 文档碎片 => dom节点 不是在dom树上一部分
// N次追加 => 1次
for(let i = page * limit; i < page * limit + limit; i++)
const item = list[i];
const div = document.createElement('div')
div.className = 'flex'
div.innerHTML = `<img src="$item.src" /><span>$item.text</span>`
fragment.appendChild(div)
// container.appendChild(div)
container.appendChild(fragment)
render(page + 1)
)
render(page);
console.timeEnd('列表时间')
renderList()
- 这里的优化点主要是:之前是创建一个div就追加一次:
div.innerHTML = `<img src="$item.src" /><span>$item.text</span>`
container.appendChild(div)
- 现在改成一次性追加,极大的提高了性能。
container.appendChild(fragment)
8. 知识点补充
- window.requestAnimationFrame()
- 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
- 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行;
- 若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
- DocumentFragments —— 文档碎片
- DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。
- 在DOM树中,文档片段被其所有的子元素所代替。因为文档片段存在于内存中,并不在DOM树中。
- 所以将子元素插入到文档片段时不会引起【页面回流】(对元素位置和几何上的计算)。
- 因此,使用文档片段通常会带来更好的性能。
1. 希望本文能对大家有所帮助,如有错误,敬请指出
2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(主页有Q)
以上是关于如何处理前端js跨域问题的主要内容,如果未能解决你的问题,请参考以下文章