Nginx add_header 只对200,201,204,206,301,302,303,304,307 这些状态码生效,对于401 405 403这些状态码是不生效的。
解决办法:
add_header Access-Control-Allow-Origin * always;
加上always参数后,无论状态码如何都会生效
const browser = await puppeteer.launch({
args: ['--no-sandbox'],
headless: true,
// executablePath:
// "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
})
const page = await browser.newPage()
page.on('dialog', async dialog => {
await dialog.dismiss()
})
await page.setViewport({
width: 1800,
height: 1200,
})
// 设置 navigator.userAgent,防止被识别为无头浏览器
await page.setUserAgent(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'
)
// 设置 navigator.webdriver,防防止被识别为程序控制的浏览器
const preloadFile = fs.readFileSync('./src/preload.js', 'utf8')
await page.evaluateOnNewDocument(preloadFile)
this.browser = browser
this.page = page
// 设置下载行为,指定下载目录
await this.page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath: './downloads' })src/preload.js
Object.defineProperty(navigator, 'webdriver', {
get: function () {
return undefined
}
})
Object.defineProperty(window, 'open', {
get: function () {
return function (url) {
window.location.href = url
}
}
}) exportInvoice(data) {
return fetch({
url: '/api/invoice/export',
method: 'post',
data: data,
responseType: 'arraybuffer',
})
}
Api.exportInvoice(params).then(res => {
loading.close()
const content = res
const blob = new Blob([content])
const fileName = 'group_invoice_list.zip'
if ('download' in document.createElement('a')) { // 非IE下载
const elink = document.createElement('a')
elink.download = fileName
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href) // 释放URL 对象
document.body.removeChild(elink)
} else { // IE10+下载
navigator.msSaveBlob(blob, fileName)
}
}).catch(e => {
loading.close()
console.log(e)
})多次绑定 window.addEventListener('resize', () => {}) 之后,安卓手机在触发 resize 事件的时候会卡死;
.border-1px {
&::after {
content: '';
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
border: 1px solid #e5e5e5;
display: block;
transform-origin: 0 0;
}
}
@media (-webkit-device-pixel-ratio: 1.5), (-webkit-min-device-pixel-ratio: 1.5) {
.border-1px {
&::after {
content: '';
position: absolute;
height: 300%;
width: 300%;
top: 0;
left: 0;
border: 2px solid #e5e5e5;
display: block;
transform: scale(0.333333, 0.33333);
transform-origin: 0 0;
}
}
}
@media (-webkit-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
.border-1px {
&::after {
content: '';
position: absolute;
height: 200%;
width: 200%;
top: 0;
left: 0;
border: 1px solid #e5e5e5;
display: block;
transform: scale(0.5, 0.5);
transform-origin: 0 0;
}
}
}
@media (-webkit-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
.border-1px {
&::after {
content: '';
position: absolute;
height: 300%;
width: 300%;
top: 0;
left: 0;
border: 2px solid #e5e5e5;
display: block;
transform: scale(0.333333, 0.333333);
transform-origin: 0 0;
}
}
}viewport-fit=cover
.page-footer{
position: fixed;
width: 100%;
bottom: 0;
left: 0;
min-height: 100px;
background: #f8f8f8;
box-sizing: initial;
}
.page-btn{
height: 72px;
width: 92%;
margin-top: 14px;
margin-left: 4%;
background: #508CEE;
background-size: cover;
border-radius: 8px;
font-size: 28px;
color: #fff;
line-height: 72px;
text-align: center;
}
.page-btn-empty {
height: 14px;
}
.page-footer-empty {
box-sizing: initial;
min-height: 100px;
width: 100%;
}
.has-padding {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
} <div class="page-footer" :class="{'has-padding': hasPadding}">
<div class="page-btn" @click="loadeData">底部按钮</div>
<div class="page-btn-empty"></div>
</div>
<div class="page-footer-empty" :class="{'has-padding': hasPadding}"></div> loadData() {
this.add = !this.add
this.$nextTick(function () {
// DOM 现在更新了
// `this` 绑定到当前实例
this.resetPadding()
})
},
resetPadding() {
if (window.innerHeight >= document.body.clientHeight) {
this.hasPadding = false
} else {
this.hasPadding = true
}
}exif-js是一个第三方的库,可以获取图片的信息,包括图片旋转角度等;如果只是为了获取图片角度,而引入整个包的话,代码体积过大;如果使用下面的方法来获取图片旋转角度的话,会大大减少代码体积;
function getOrientation(file) {
return new Promise((resolve, reject) => {
try {
const reader = new FileReader()
reader.onload = function(e) {
const view = new DataView(e.target.result)
if (view.getUint16(0, false) !== 0xffd8) {
resolve(-2) // 不是jpeg
}
const length = view.byteLength
let offset = 2
while (offset < length) {
if (view.getUint16(offset + 2, false) <= 8) {
resolve(-1) // 不包含旋转信息
}
const marker = view.getUint16(offset, false)
offset += 2
if (marker === 0xffe1) {
offset += 2
if (view.getUint32(offset, false) !== 0x45786966) {
resolve(-1) // 不包含旋转信息
}
const little = view.getUint16((offset += 6), false) === 0x4949
offset += view.getUint32(offset + 4, little)
const tags = view.getUint16(offset, little)
offset += 2
for (let i = 0; i < tags; i += 1) {
if (view.getUint16(offset + i * 12, little) === 0x0112) {
resolve(view.getUint16(offset + i * 12 + 8, little))
}
}
} else if ((marker & 0xff00) !== 0xff00) {
break
} else {
offset += view.getUint16(offset, false)
}
}
resolve(-1) // 不包含旋转信息
}
reader.readAsArrayBuffer(file)
} catch (e) {
reject(e)
}
})
}参考自: accessing-jpeg-exif-rotation-data-in-javascript-on-the-client-side
const XLSX = require('xlsx')
const fs = require('fs')
const path = require('path')
const LetterMap = {
A: 1,
B: 2,
C: 3,
D: 4,
E: 5,
F: 6,
G: 7,
H: 8,
I: 9,
J: 10,
K: 11,
L: 12,
M: 13,
N: 14,
O: 15,
P: 17,
Q: 18,
R: 19,
S: 20
}
const transferData = function (data) {
const sheetData = data.Sheets[data.SheetNames[0]]
const backUpCellMap = {}
const result = {}
for (let key in sheetData) {
const cell = sheetData[key]
const cellKey = key.substring(1, key.length)
const rowKey = key.substring(0, 1)
if (cell.t) {
if (!result[cellKey]) {
result[cellKey] = {
value: []
}
}
if (LetterMap[rowKey] > 1 && LetterMap[rowKey] > result[cellKey].value.length + 1) {
for(let letter in LetterMap) {
if (LetterMap[letter] === LetterMap[rowKey] - 1) {
result[cellKey].value.push(backUpCellMap[letter])
break
}
}
} else {
backUpCellMap[rowKey] = cell.v || ''
}
result[cellKey].value.push(cell.v || '')
if (cellKey === '2' && cell.l && cell.l.Target) {
result[cellKey].link = cell.l.Target
}
}
}
let dataList = []
for (let key in result) {
const row = result[key]
row.value.push(row.link ? row.link : '')
dataList.push(row.value)
}
return JSON.stringify(dataList)
}
const filePath = path.join(__dirname, 'src/a.xlsx')
const fileData = XLSX.readFile(filePath)
const result = transferData(fileData)
console.log(result)