Halz

Halz 查看完整档案

填写现居城市  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

Halz 提出了问题 · 2020-12-31

node图片上传的token过期后重签问题

第一次签的token过期后,再次请求接口获取token时,生成的新的token与过期的token是一样的。。

const qiniu = require('qiniu')
const accessKey = ''
const secretKey = ''
const zone = 'qiniu.zone.Zone_z2'
const bucket = 'testzone'
const mac = new qiniu.auth.digest.Mac(accessKey,secretKey)
let options={
    scope: bucket,
    expires:7200
}
let putPolicy = new qiniu.rs.PutPolicy(options)

let luploadToken = putPolicy.uploadToken(mac)

module.exports = luploadToken

这是node生成token的代码块。。
是不是漏了参数,第一次用,不太熟悉

试过重启node,生成的还是一样的
求大佬指导

关注 1 回答 0

Halz 赞了文章 · 2019-10-10

【JS 口袋书】第 4 章:JS 引擎底层的工作原理

作者:valentinogagliardi
译者:前端小智
来源:github

阿里云最近在做活动,低至2折,有兴趣可以看看:
https://promotion.aliyun.com/...

为了保证的可读性,本文采用意译而非直译。

有没有想过浏览器如何读取和运行JS代码? 这看起来很神奇,我们可以通过浏览器提供的控制台来了解背后的一些原理。

在Chrome中打开浏览器控制台,然后查看Sources这栏,在右侧可以到一个 Call Stack 盒子。

clipboard.png

JS 引擎是一个可以编译和解释我们的JS代码强大的组件。 最受欢迎的JS 引擎是V8,由 Google Chrome 和 Node.j s使用,SpiderMonkey 用于Firefox,以及Safari/WebKit使用的 JavaScriptCore。

虽然现在 JS 引擎不是帮我们处理全面的工作。但是每个引擎中都有一些较小的组件为我们做繁琐的的工作。

其中一个组件是调用堆栈(Call Stack),与全局内存和执行上下文一起运行我们的代码。

Js 引擎和全局内存(Global Memory)

JavaScript 是编译语言同时也是解释语言。信不信由你,JS 引擎在执行代码之前只需要几微秒就能编译代码。

这听起来很神奇,对吧?这种神奇的功能称为JIT(及时编译)。这个是一个很大的话题,一本书都不足以描述JIT是如何工作的。但现在,我们午饭可以跳过编译背后的理论,将重点放在执行阶段,尽管如此,这仍然很有趣。

考虑以下代码:

var num = 2;
function pow(num) {
    return num * num;
}

如果问你如何在浏览器中处理上述代码? 你会说些什么? 你可能会说“浏览器读取代码”或“浏览器执行代码”。

现实比这更微妙。首先,读取这段代码的不是浏览器,是JS引擎。JS引擎读取代码,一旦遇到第一行,就会将几个引用放入全局内存

全局内存(也称为堆)JS引擎保存变量和函数声明的地方。因此,回到上面示例,当 JS引擎读取上面的代码时,全局内存中放入了两个绑定。

clipboard.png

即使示例只有变量和函数,也要考虑你的JS代码在更大的环境中运行:在浏览器中或在Node.js中。 在这些环境中,有许多预定义的函数和变量,称为全局变量。 全球记忆将比num和pow更多。

上例中,没有执行任何操作,但是如果我们像这样运行函数会怎么样呢:

var num = 2;
function pow(num) {
    return num * num;
}
pow(num);

现在事情变得有趣了。当函数被调用时,JavaScript引擎会为全局执行上下文调用栈腾出空间。

JS引擎:它们是如何工作的? 全局执行上下文和调用堆栈

刚刚了解了 JS引擎如何读取变量和函数声明,它们最终被放入了全局内存(堆)中。

但现在我们执行了一个JS函数,JS引擎必须处理它。怎么做?每个JS引擎中都有一个基本组件,叫调用堆栈

调用堆栈是一个堆栈数据结构:这意味着元素可以从顶部进入,但如果它们上面有一些元素,它们就不能离开,JS 函数就是这样的。

一旦执行,如果其他函数仍然被阻塞,它们就不能离开调用堆栈。请注意,这个有助于你理解“JavaScript是单线程的”这句话。

回到我们的例子,当函数被调用时,JS引擎将该函数推入调用堆栈

clipboard.png

同时,JS 引擎还分配了一个全局执行上下文,这是运行JS代码的全局环境,如下所示

clipboard.png

想象全局执行上下文是一个海洋,其中全局函数像鱼一样游动,多美好! 但现实远非那么简单, 如果我函数有一些嵌套变量或一个或多个内部函数怎么办?

即使是像下面这样的简单变化,JS引擎也会创建一个本地执行上下文:

var num = 2;
function pow(num) {
    var fixed = 89;
    return num * num;
}
pow(num);

注意,我在pow函数中添加了一个名为fixed的变量。在这种情况下,pow函数中会创建一个本地执行上下文,fixed 变量被放入pow函数中的本地执行上下文中。

对于嵌套函数的每个嵌套函数,引擎都会创建更多的本地执行上下文。

JavaScript 是单线程和其他有趣的故事

JavaScript是单线程的,因为只有一个调用堆栈处理我们的函数。也就是说,如果有其他函数等待执行,函数就不能离开调用堆栈。

在处理同步代码时,这不是问题。例如,两个数字之间的和是同步的,以微秒为单位。但如果涉及异步的时候,怎么办呢?

幸运的是,默认情况下JS引擎是异步的。即使它一次执行一个函数,也有一种方法可以让外部(如:浏览器)执行速度较慢的函数,稍后探讨这个主题。

当浏览器加载某些JS代码时,JS引擎会逐行读取并执行以下步骤:

  • 将变量和函数的声明放入全局内存(堆)中
  • 将函数的调用放入调用堆栈
  • 创建全局执行上下文,在其中执行全局函数
  • 创建多个本地执行上下文(如果有内部变量或嵌套函数)

到目前为止,对JS引擎的同步机制有了基本的了解。 在接下来的部分中,讲讲 JS 异步工作原理。

异步JS,回调队列和事件循环

全局内存(堆),执行上下文和调用堆栈解释了同步 JS 代码在浏览器中的运行方式。 然而,我们遗漏了一些东西,当有一些异步函数运行时会发生什么?

请记住,调用堆栈一次可以执行一个函数,甚至一个阻塞函数也可以直接冻结浏览器。 幸运的是JavaScript引擎是聪明的,并且在浏览器的帮助下可以解决问题。

当我们运行一个异步函数时,浏览器接受该函数并运行它。考虑如下代码:

setTimeout(callback, 10000);
function callback(){
    console.log('hello timer!');
}

setTimeout 大家都知道得用得很多次了,但你可能不知道它不是内置的JS函数。 也就是说,当JS 出现,语言中没有内置的setTimeout

setTimeout浏览器API( Browser API)的一部分,它是浏览器免费提供给我们的一组方便的工具。这在实战中意味着什么?由于setTimeout是一个浏览器的一个Api,函数由浏览器直接运行(它会在调用堆栈中出现一会儿,但会立即删除)。

10秒后,浏览器接受我们传入的回调函数并将其移动到回调队列(Callback Queu)中。。考虑以下代码

var num = 2;
function pow(num) {
    return num * num;
}
pow(num);
setTimeout(callback, 10000);
function callback(){
    console.log('hello timer!');
}

示意图如下:

clipboard.png

如你所见,setTimeout在浏览器上下文中运行。 10秒后,计时器被触发,回调函数准备运行。 但首先它必须通过回调队列(Callback Queue)。 回调队列是一个队列数据结构,回调队列是一个有序的函数队列。

每个异步函数在被放入调用堆栈之前必须通过回调队列,但这个工作是谁做的呢,那就是事件循环(Event Loop)。

事件循环只有一个任务:它检查调用堆栈是否为空。如果回调队列中(Callback Queue)有某个函数,并且调用堆栈是空闲的,那么就将其放入调用堆栈中。

完成后,执行该函数。 以下是用于处理异步和同步代码的JS引擎的图:

clipboard.png

想象一下,callback() 已准备好执行,当 pow() 完成时,调用堆栈(Call Stack) 为空,事件循环(Event Look) 将 callback() 放入调用堆中。大概就是这样,如果你理解了上面的插图,那么你就可以理解所有的JavaScript了。

回调地狱和 ES6 中的Promises

JS 中回调函数无处不在,它们用于同步和异步代码。 考虑如下map方法:

function mapper(element){
    return element * 2;
}
[1, 2, 3, 4, 5].map(mapper);

mapper是一个在map内部传递的回调函数。上面的代码是同步的,考虑异步的情况:

function runMeEvery(){
    console.log('Ran!');
}
setInterval(runMeEvery, 5000);

该代码是异步的,我们在setInterval中传递回调runMeEvery。回调在JS中无处不在,因此就会出现了一个问题:回调地狱

JavaScript 中的回调地狱指的是一种编程风格,其中回调嵌套在回调函数中,而回调函数又嵌套在其他回调函数中。由于 JS 异步特性,js 程序员多年来陷入了这个陷阱。

说实话,我从来没有遇到过极端的回调金字塔,这可能是因为我重视可读代码,而且我总是坚持这个原则。如果你在遇到了回调地狱的问题,说明你的函数做得太多。

这里不会讨论回调地狱,如果你好奇,有一个网站,callbackhell.com,它更详细地探索了这个问题,并提供了一些解决方案。

我们现在要关注的是ES6的 Promises。ES6 Promises是JS语言的一个补充,旨在解决可怕的回调地狱。但什么是 Promises 呢?

JS的 Promise是未来事件的表示。 Promise 可以以成功结束:用行话说我们已经解决了resolved(fulfilled)。 但如果 Promise 出错,我们会说它处于拒绝(rejected )状态。 Promise 也有一个默认状态:每个新的 Promise 都以挂起(pending)状态开始。

创建和使用 JavaScript 的 Promises

要创建一个新的 Promise,可以通过传递回调函数来调用 Promise 构造函数。回调函数可以接受两个参数:resolvereject。如下所示:

const myPromise = new Promise(function(resolve){
    setTimeout(function(){
        resolve()
    }, 5000)
});

如下所示,resolve是一个函数,调用它是为了使Promise 成功,别外也可以使用 reject 来表示调用失败。

const myPromise = new Promise(function(resolve, reject){
    setTimeout(function(){
        reject()
    }, 5000)
});

注意,在第一个示例中可以省略reject,因为它是第二个参数。但是,如果打算使用reject,则不能忽略resolve,如下所示,最终将得到一个resolved 的承诺,而非 reject

// 不能忽略 resolve !
const myPromise = new Promise(function(reject){
    setTimeout(function(){
        reject()
    }, 5000)
});

现在,Promises看起来并不那么有用,我们可以向它添加一些数据,如下所示:

const myPromise = new Promise(function(resolve) {
  resolve([{ name: "Chris" }]);
});

但我们仍然看不到任何数据。 要从Promise中提取数据,需要链接一个名为then的方法。 它需要一个回调来接收实际数据:

const myPromise = new Promise(function(resolve, reject) {
  resolve([{ name: "Chris" }]);
});
myPromise.then(function(data) {
    console.log(data);
});

Promises 的错误处理

对于同步代码而言,JS 错误处理大都很简单,如下所示:

function makeAnError() {
  throw Error("Sorry mate!");
}
try {
  makeAnError();
} catch (error) {
  console.log("Catching the error! " + error);
}

将会输出:

Catching the error! Error: Sorry mate!

现在尝试使用异步函数:

function makeAnError() {
  throw Error("Sorry mate!");
}
try {
  setTimeout(makeAnError, 5000);
} catch (error) {
  console.log("Catching the error! " + error);

由于setTimeout,上面的代码是异步的,看看运行会发生什么:

  throw Error("Sorry mate!");
  ^
Error: Sorry mate!
    at Timeout.makeAnError [as _onTimeout] (/home/valentino/Code/piccolo-javascript/async.js:2:9)

这次的输出是不同的。错误没有通过catch块,它可以自由地在堆栈中向上传播。

那是因为try/catch仅适用于同步代码。 如果你很好奇,Node.js中的错误处理会详细解释这个问题。

幸运的是,Promise 有一种处理异步错误的方法,就像它们是同步的一样:

const myPromise = new Promise(function(resolve, reject) {
  reject('Errored, sorry!');
});

在上面的例子中,我们可以使用catch处理程序处理错误:

const myPromise = new Promise(function(resolve, reject) {
  reject('Errored, sorry!');
});
myPromise.catch(err => console.log(err));

我们也可以调用Promise.reject()来创建和拒绝一个Promise

Promise.reject({msg: 'Rejected!'}).catch(err => console.log(err));

Promises 组合:Promise.all,Promise.allSettled, Promise.any

Promise API 提供了许多将Promise组合在一起的方法。 其中最有用的是Promise.all,它接受一个Promises数组并返回一个Promise。 如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。

Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。

较新版本的V8也将实现两个新的组合:Promise.allSettledPromise.anyPromise.any仍然处于提案的早期阶段:在撰写本文时,仍然没有浏览器支持它。

Promise.any可以表明任何Promise是否fullfilled。 与 Promise.race的区别在于Promise.any不会拒绝即使其中一个Promise被拒绝。

无论如何,两者中最有趣的是 Promise.allSettled,它也是 Promise 数组,但如果其中一个Promise拒绝,它不会短路。 当你想要检查Promise数组是否全部已解决时,它是有用的,无论最终是否拒绝,可以把它想象成Promise.all 的反对者。

异步进化:从Promises 到 async/await

ECMAScript 2017 (ES8)的出现,推出了新的语法诞生了async/await

async/await只是Promise 语法糖。它只是一种基于Promises编写异步代码的新方法, async/await 不会以任何方式改变JS,请记住,JS必须向后兼容旧浏览器,不应破坏现有代码。

来个例子:

const myPromise = new Promise(function(resolve, reject) {
  resolve([{ name: "Chris" }]);
});
myPromise.then((data) => console.log(data))

使用async/await, 我们可以将Promise包装在标记为async的函数中,然后等待结果的返回:

const myPromise = new Promise(function(resolve, reject) {
  resolve([{ name: "Chris" }]);
});
async function getData() {
  const data = await myPromise;
  console.log(data);
}
getData();

有趣的是,async 函数也会返回Promise,你也可以这样做:

async function getData() {
  const data = await myPromise;
  return data;
}
getData().then(data => console.log(data));

那如何处理错误? async/await提一个好处就是可以使用try/catch。 再看一下Promise,我们使用catch处理程序来处理错误:

const myPromise = new Promise(function(resolve, reject) {
  reject('Errored, sorry!');
});
myPromise.catch(err => console.log(err));

使用async函数,我们可以重构以上代码:

async function getData() {
  try {
    const data = await myPromise;
    console.log(data);
    // or return the data with return data
  } catch (error) {
    console.log(error);
  }
}
getData();

并不是每个人都喜欢这种风格。try/catch会使代码变得冗长,在使用try/catch时,还有另一个怪异的地方需要指出,如下所示:

async function getData() {
  try {
    if (true) {
      throw Error("Catch me if you can");
    }
  } catch (err) {
    console.log(err.message);
  }
}
getData()
  .then(() => console.log("I will run no matter what!"))
  .catch(() => console.log("Catching err"));

运行结果:

clipboard.png

以上两个字符串都会打印。 请记住, try/catch 是一个同步构造,但我们的异步函数产生一个Promise。 他们在两条不同的轨道上行驶,比如两列火车。但他们永远不会见面, 也就是说,throw 抛出的错误永远不会触发getData()catch方法。

实战中,我们不希望throwthen的处理程序。 一种的解决方案是从函数返回Promise.reject()

async function getData() {
  try {
    if (true) {
      return Promise.reject("Catch me if you can");
    }
  } catch (err) {
    console.log(err.message);
  }
}

现在按预期处理错误

getData()
  .then(() => console.log("I will NOT run no matter what!"))
  .catch(() => console.log("Catching err"));
"Catching err" // 输出

除此之外,async/await似乎是在JS中构建异步代码的最佳方式。 我们可以更好地控制错误处理,代码看起来也更清晰。

总结

JS 是一种用于Web的脚本语言,具有先编译然后由引擎解释的特性。 在最流行的JS引擎中,有谷歌Chrome和Node.js使用的V8,有Firefox构建的SpiderMonkey,以及Safari使用的JavaScriptCore

JS引擎包含很有组件:调用堆栈、全局内存(堆)、事件循环、回调队列。所有这些组件一起工作,完美地进行了调优,以处理JS中的同步和异步代码。

JS引擎是单线程的,这意味着运行函数只有一个调用堆栈。这一限制是JS异步本质的基础:所有需要时间的操作都必须由外部实体(例如浏览器)或回调函数负责。

为了简化异步代码流,ECMAScript 2015 给我们带来了Promise。 Promise 是一个异步对象,用于表示任何异步操作的失败或成功。 但改进并没有止步于此。 在2017年,async/ await诞生了:它是Promise的一种风格弥补,使得编写异步代码成为可能,就好像它是同步的一样。

思考

  • 浏览器如何理解 JS 代码?
  • 调用堆栈的主要任务是什么?
  • 你能描述一下 JS 引擎的主要组件以及它们是如何协同工作的吗?
  • 微任务队列是做什么的 ?
  • Promise 是什么?
  • 是否可以处理异步代码中的错误? 如果可以,怎么做?
  • 你能说出浏览器API的几个方法吗

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://github.com/valentinog...

交流

阿里云最近在做活动,低至2折,有兴趣可以看看:https://promotion.aliyun.com/...

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq449245884/xiaozhi

因为篇幅的限制,今天的分享只到这里。如果大家想了解更多的内容的话,可以去扫一扫每篇文章最下面的二维码,然后关注咱们的微信公众号,了解更多的资讯和有价值的内容。

clipboard.png

每次整理文章,一般都到2点才睡觉,一周4次左右,挺苦的,还望支持,给点鼓励

查看原文

赞 13 收藏 11 评论 0

Halz 收藏了文章 · 2019-09-29

那些我常用的 Chrome 扩展神器

Chrome仍然是目前最好的浏览器,每天用Chrome 必然少不了使用扩展来增强浏览器的功能,这里整理下我常用的Chrome 扩展。

油猴

这个简直神器,所以第一个推荐 https://www.tampermonkey.net/ 下载后在https://greasyfork.org/zh-CN 这里安装对应的脚本。
image.png

常用的脚本比如百度网盘直链下载
image.png
全网VIP视频免费观看

image.png
之前已经写过
Chrome 浏览器扩展神器油猴
Chrome 浏览器扩展神器暴力猴
下载地址 https://chrome.google.com/web...

取字

之前写过ocr 那些你可能不知道的 ocr 图片文字识别工具,虽然有桌面版工具天若ocr,但在浏览器里还是用取字这个扩展方便http://willingstudio.com/#ins... ,它具有通识化场景的 OCR 识别功能浏览器插件,快速框选,可精确识别图片或者视频中的文本。

它提供本地安装和Chrome应用商店安装https://chrome.google.com/web...://willingstudio.com 安装方法上面也有,上不了Google推荐下面的方法。
image.png

使用效果如图:
image.png
image.png

WEB前端助手

这个扩展包含多个独立小应用,比如:Json工具、代码美化、代码压缩、二维码、Postman、markdown、网页油猴、便签笔记、信息加密与解密、随机密码生成、Crontab等等!
image.png
扩展地址 https://chrome.google.com/webstore/detail/web%E5%89%8D%E7%AB%AF%E5%8A%A9%E6%89%8Bfehelper/pkgccpejnmalmdinmhkkfafefagiiiad?hl=zh-CN

listen1

Listen 1可以搜索和播放来自网易云音乐,虾米,QQ音乐,酷狗音乐,酷我音乐网站的歌曲,让你的曲库更全面,不用一个个找了。https://listen1.github.io/lis...

image.png
之前也写过 那些你可能不知道的网易云音乐奇技淫巧

极简 Json 格式化

这个用来看json格式的接口最方便了,由https://atool.vip/#/提供。
image.png

下载地址 https://chrome.google.com/webstore/detail/%E6%9E%81%E7%AE%80-json-%E6%A0%BC%E5%BC%8F%E5%8C%96/fhlnfdmpnhhakjljpllkigcegcejpoec?hl=zh-CN

百度网盘助手

用来下载百度网盘的工具 增加高速下载按钮。

image.png

下载地址 https://github.com/high-speed-downloader/high-speed-downloader

图片助手

一款Chrome浏览器中用于嗅探、分析网页图片、图片筛选、下载等功能及收藏、检索、分享等在线服务的扩展程序,无论图片是使用flash载入还是动态载入的,扩展都能很好地应对,真正做到所见即所得 http://www.pullywood.com/ImageAssistant/
image.png

下载地址https://chrome.google.com/webstore/detail/imageassistant-batch-imag/dbjbempljhcmhlfpfacalomonjpalpko

微博图床

一个上传图片到微博并生成外链的 Chrome 浏览器扩展https://github.com/Semibold/Weibo-Picture-Store,支持同步到微相册 ,需要浏览器登录微博。
image.png

下载地址 https://chrome.google.com/web...

谷歌访问助手

这个上谷歌必备
image.png

下载地址https://github.com/haotian-wa... 如果下载不了公众号回复 谷歌 获取

爱搜资源云盘助手

之前写过文章 没有提取码怎么获取百度网盘资源?,不用自己输入提取码。https://www.aisouziyuan.com/
image.png

下载地址 https://chrome.google.com/web...

一键视频下载器

比如微博上的视频,点击按钮就能显示当前可以下载的视频,直接点击下载到本地。
image.png
下载地址 https://chrome.google.com/webstore/detail/one-click-video-downloade/bhepgcoaibmmehlmckhlmbdgcemhidcg

翻译

co-trans-ext 是一个集搜狗翻译、百度翻译、谷歌翻译、有道翻译、金山词霸于一体的翻译扩展。各平台可随时切换,取长补短,更适合于阅读各领域的文档。不止于翻译,解析详细,更利于对各门语言的深入学习与理解。支持划词翻译和网页翻译。
下载后将crx后缀改为zip,然后拖到扩展中,除了翻译还提供发音,非常好用。

clipboard.png

下载地址:https://github.com/Coande/co-trans-ext

截图

它满足截图所有的需求,截取可见网页,选择区域,整个网页,录屏,捕获整个页面或任何部分,矩形,圆形,箭头,线条和文字,模糊敏感信息,一键上传分享注释。
image.png
image.png

下载地址https://chrome.google.com/webstore/detail/awesome-screenshot-screen/nlipoenfbbikpbjkfpfillcgkoblgpmj

聊天

和浏览相同网页的人实时聊天,发弹幕!http://yiyechat.com/
该扩展可以在任意网页增加一个简洁的聊天盒,让您可以和浏览当前网站的其他用户聊天!

这是谷歌页面的聊天

clipboard.png

下载地址 https://chrome.google.com/web...

复制图片中文字

这个Chrome扩展厉害了 ,能直接复制图片中文字,功能远超普通OCR软件 https://projectnaptha.com/

clipboard.png

你平常用了哪些不错的扩展,也欢迎评论给我推荐下。

推荐阅读:

那些你可能不知道的浏览器奇技淫巧

如何发一条空白的朋友圈

如何在电脑上登陆多个微信

如何提取公积金 9 天到账

免费在线听周杰伦歌曲

那些你可能不知道的微信奇技淫巧

如何在豆瓣租房小组快速找到满意的房子

10%+10% 不等于 0.2?

Chrome 浏览器扩展神器油猴

免费星球

公众号:苏生不惑

扫描二维码关注

查看原文

Halz 回答了问题 · 2019-09-29

前端跨域请求tp5后端出现错误:It does not have HTTP ok status

经过查看代码发现:是前端那边的vue项目没有使用 qs 将参数stringify,经过处理后就能正常进行请求了

关注 3 回答 3

Halz 提出了问题 · 2019-09-29

前端跨域请求tp5后端出现错误:It does not have HTTP ok status

第一次遇到这个问题

错误代码:

Access to XMLHttpRequest at 'http://localhost:8081/public/getContent' from origin 'http://localhost:19601' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

但是,我试过用同一个项目里面的其他app的接口测试,却可以正常返回数据,我的跨域配置应该没问题

tp5跨域配置:

header("Access-Control-Allow-Origin:*");
header("Access-Control-Allow-Methods:*");
header("Access-Control-Allow-Credentials",true);
header("Access-Control-Allow-Headers:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X_Requested_With,If-Modified-Since,Cache-Control,Content-Type, Accept-Language, Origin, Accept-Encoding");

而且出现错误的app的接口中,需要参数的接口都会出现这个错误,不需要参数的是可以正常返回数据的

毫无头绪,各位路过的大佬指点一下

ps:国庆节快乐!


关注 3 回答 3

Halz 赞了文章 · 2019-09-25

即将是史上最全的meta大全

本文的目的是搜集当前主流的meta配置,方便开发者快速开发调试。在这里不会做各种meta的深入分析,只是简单的介绍,让大家知道有这个东西。

meta简述

  • meta用于描述 HTML 文档的元数据。通常用于指定网页的描述,关键词,作者及其他元数据。
  • 元数据可以被使用浏览器(如何显示内容或加载页面),搜索引擎(关键词),或其他 Web 服务调用。
  • meta从一定程度上影响seo

meta支持哪些属性

属性描述
charsetcharacter_set定义文档的字符编码。
contenttext定义与 http-equiv 或 name 属性相关的元信息。
http-equivcontent-type, default-style, refresh把 content 属性关联到 HTTP 头部。
nameapplication-name, author, description, generator, keywords把 content 属性关联到一个名称。
schemeformat/URIHTML5不支持。 定义用于翻译 content 属性值的格式。

http-equiv

meta标签上的http-equiv属性与http头部信息相关,而且是响应头,因为html本质上是通过服务器响应得到的。http-equiv用于伪装 HTTP 响应头部信息。那么http-equiv有哪些类型呢?让我们一起看下。

描述
cache-control控制文档的缓存机制。允许的值如下:public:所有内容都将被缓存(客户端和代理服务器都可缓存);private:内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存);no-cache:不缓存,前提是通过服务器的缓存验证机制,如过期,内容改变等校验规则;no-store:所有内容都不会被缓存到缓存或 Internet 临时文件中(设置了貌似无效,还是说不会出现在响应头吗?哪位大神可以解释下)
content-language响应体的语言。如zh-CN, en-US(设置了貌似无效)
content-type返回内容的MIME类型
date原始服务器消息发出的时间,GMT时间格式
expires响应过期的日期和时间,GMT时间格式<meta http-equiv="expires" content="Fri, 30 Dec 2011 12:00:00 GMT">(设置了貌似无效)
last-modified请求资源的最后修改时间,GMT时间格式(设置了貌似无效)
location用来重定向接收方到非请求URL的位置来完成请求或标识新的资源(设置了貌似无效)
refresh定义间隔多久后刷新页面。单位是秒。
set-cookie创建一个 cookie ,包含 cookie 名,cookie 值,过期时间。(设置了貌似无效)
window-target用来防止别人在框架里调用自己的页面。<meta http-equiv="Window-target" content="_top">(设置了貌似无效)
Pragma向后兼容只支持 HTTP/1.0 协议的缓存服务器,那时候 HTTP/1.1 协议中的 Cache-Control 还没有出来。<meta http-equiv="Pragma" content="no-cache">(设置了貌似无效)

注意:以上都是在chrome浏览器最新版本, vue dev环境下测试的,不代表所有浏览器和服务器表现。

常见meta

  1. 指定字符编码

    <meta charset="UTF-8">
  2. IE杀手,推荐所有前端工程师采用,让我们干掉IE的市场份额。

    <!-- renderer适用于国产双内核浏览器 -->
    <!-- 使用Blink(Webkit) -->
    <meta name="renderer" content="webkit">
    <!-- IE兼容模式,使用ie低版本兼容 -->
    <meta name="renderer" content="ie-comp">
    <!-- IE标准模式,使用ie高版本兼容 -->
    <meta name="renderer" content="ie-stand">
    <!-- force-rendering适用于其他双内核浏览器 -->
    <meta name="force-rendering" content="webkit">
    <!-- 强化对IE的兼容性,强制IE使用最新版标准模式渲染或者使用Chrome Frame渲染 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  3. viewport常见设置,一般适用于移动端。视口宽度设为理想宽度,禁止缩放。

    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
  4. meta三剑客

    <meta name="description" content="Tusi博客,专注大前端技术架构与分享,关注用户体验">
    <meta name="keyword" content="Tusi博客,web前端,nodejs全栈,响应式,用户体验">
    <meta name="author" content="Tusi">
  5. UC浏览器私有meta

    <!-- 横屏/竖屏 -->
    <meta name="screen-orientation" content="landscape|portrait">
    <!-- 全屏 -->
    <meta name="full-screen" content="yes">
    <!-- 缩放不出滚动条 -->
    <meta name="viewport" content="uc-fitscreen=yes|no">
    <!-- 排版,fitscreen简化页面,适合阅读省流量,standard模式和标准浏览器一致 -->
    <meta name="layoutmode" content="fitscreen|standard" 
    <!-- 夜间模式的启用和禁用 -->
    <meta name="nightmode" content="enable|disable"/>
    <!-- 强制图片显示 -->
    <meta name="imagemode" content="force"/>
    <!-- 强制图片显示,只作用于单图 -->
    <img data-original="..." show="force">
    <!-- 应用模式,默认全屏,禁止长按菜单,禁止手势,标准排版,以及强制图片显示。 -->
    <meta name="browsermode" content="application">
  6. QQ浏览器X5内核私有meta(现在微信内置浏览器的内核也是X5哦)

    <!-- 横屏/竖屏 -->
    <meta name="x5-orientation" content="landscape|portrait">
    <!-- 全屏 -->
    <meta name="x5-fullscreen" content="true">
    <!-- 应用模式 -->
    <meta name="x5-page-mode" content="app">
  7. 苹果机适配

    <!-- "添加到主屏幕“后,全屏显示 -->
    <meta name="apple-touch-fullscreen" content="yes">
    <!-- 隐藏菜单栏和状态栏,类似于应用模式 -->
    <meta name="apple-mobile-web-app-capable" content="yes|no">
    <!-- 设置状态栏颜色,貌似只有default白色,black黑色,black-translucent灰色半透明 -->
    <meta name=”apple-mobile-web-app-status-bar-style” content=black”>
    <!-- 取消电话号码识别,防止误触拨号 -->
    <meta name="format-detection" content="telephone=no">
  8. 其他优化和适配手段

    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
    <meta name="HandheldFriendly" content="true">
    
    <!-- 微软的老式浏览器 -->
    <meta name="MobileOptimized" content="320">
    
    <!-- windows phone 点击无高光 -->
    <meta name="msapplication-tap-highlight" content="no">
    
    <!-- robots 用来告诉搜索机器人哪些页面需要被检索 -->
    <!-- index 搜索引擎抓取这个页面 -->
    <!-- noindex 搜索引擎不抓取这个页面 -->
    <!-- follow 抓取外链 -->
    <!-- nofollow 不抓取外链 -->
    <meta name="robots" content="index,follow">
    <meta name="robots" content="index,nofollow">
    <meta name="robots" content="noindex,follow">
    <meta name="robots" content="noindex,nofollow">
    
    <!-- referrer 控制http请求头的referer,暂时没想到什么实际应用场景 -->
    <!-- no-referrer 不发referer -->
    <!-- origin 只发送origin部分 -->
    <!-- no-referrer-when-downgrade 默认值,当目的地是先验安全的(https->https)则发送origin作为 referrer,但是当目的地是较不安全的(https->http)时则不发送referrer -->。
    <!-- origin-when-crossorigin 在同源请求下,发送完整的URL(不含查询参数),其他情况下则仅发送当前文档的origin -->
    <!-- unsafe-URL 在同源请求下,发送完整的URL(不含查询参数) -->
    <meta name="referrer" content="no-referrer">
    
    <!-- og: Open Graph Protocol,一种友好的配置,让自己的网站在社交网络分享中更得心应手,更多的配置可以去自行搜索 -->
    <!-- og:type 告诉SNS,我这是一个什么类型的网站 -->
    <meta property="og:type" content="article"/>
    <!-- og:title 告诉SNS,分享时告诉用户我这个网站的标题是什么,别自己瞎搞个标题 -->
    <meta property="og:title" content="Tusi博客"/>
    <meta property="og:url" content="https://blog.wbjiang.cn"/>
    <!-- og:image 缩略图 -->
    <meta property="og:image" content="/static/imgs/thumbnail.png"/>
    <meta property="og:description" content="专注于大前端技术架构与分享,关注用户体验"/>

首发链接


往期精彩:


扫一扫下方小程序码或搜索Tusi博客,即刻阅读最新文章!

Tusi博客

查看原文

赞 29 收藏 25 评论 1

Halz 收藏了文章 · 2019-09-25

即将是史上最全的meta大全

本文的目的是搜集当前主流的meta配置,方便开发者快速开发调试。在这里不会做各种meta的深入分析,只是简单的介绍,让大家知道有这个东西。

meta简述

  • meta用于描述 HTML 文档的元数据。通常用于指定网页的描述,关键词,作者及其他元数据。
  • 元数据可以被使用浏览器(如何显示内容或加载页面),搜索引擎(关键词),或其他 Web 服务调用。
  • meta从一定程度上影响seo

meta支持哪些属性

属性描述
charsetcharacter_set定义文档的字符编码。
contenttext定义与 http-equiv 或 name 属性相关的元信息。
http-equivcontent-type, default-style, refresh把 content 属性关联到 HTTP 头部。
nameapplication-name, author, description, generator, keywords把 content 属性关联到一个名称。
schemeformat/URIHTML5不支持。 定义用于翻译 content 属性值的格式。

http-equiv

meta标签上的http-equiv属性与http头部信息相关,而且是响应头,因为html本质上是通过服务器响应得到的。http-equiv用于伪装 HTTP 响应头部信息。那么http-equiv有哪些类型呢?让我们一起看下。

描述
cache-control控制文档的缓存机制。允许的值如下:public:所有内容都将被缓存(客户端和代理服务器都可缓存);private:内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存);no-cache:不缓存,前提是通过服务器的缓存验证机制,如过期,内容改变等校验规则;no-store:所有内容都不会被缓存到缓存或 Internet 临时文件中(设置了貌似无效,还是说不会出现在响应头吗?哪位大神可以解释下)
content-language响应体的语言。如zh-CN, en-US(设置了貌似无效)
content-type返回内容的MIME类型
date原始服务器消息发出的时间,GMT时间格式
expires响应过期的日期和时间,GMT时间格式<meta http-equiv="expires" content="Fri, 30 Dec 2011 12:00:00 GMT">(设置了貌似无效)
last-modified请求资源的最后修改时间,GMT时间格式(设置了貌似无效)
location用来重定向接收方到非请求URL的位置来完成请求或标识新的资源(设置了貌似无效)
refresh定义间隔多久后刷新页面。单位是秒。
set-cookie创建一个 cookie ,包含 cookie 名,cookie 值,过期时间。(设置了貌似无效)
window-target用来防止别人在框架里调用自己的页面。<meta http-equiv="Window-target" content="_top">(设置了貌似无效)
Pragma向后兼容只支持 HTTP/1.0 协议的缓存服务器,那时候 HTTP/1.1 协议中的 Cache-Control 还没有出来。<meta http-equiv="Pragma" content="no-cache">(设置了貌似无效)

注意:以上都是在chrome浏览器最新版本, vue dev环境下测试的,不代表所有浏览器和服务器表现。

常见meta

  1. 指定字符编码

    <meta charset="UTF-8">
  2. IE杀手,推荐所有前端工程师采用,让我们干掉IE的市场份额。

    <!-- renderer适用于国产双内核浏览器 -->
    <!-- 使用Blink(Webkit) -->
    <meta name="renderer" content="webkit">
    <!-- IE兼容模式,使用ie低版本兼容 -->
    <meta name="renderer" content="ie-comp">
    <!-- IE标准模式,使用ie高版本兼容 -->
    <meta name="renderer" content="ie-stand">
    <!-- force-rendering适用于其他双内核浏览器 -->
    <meta name="force-rendering" content="webkit">
    <!-- 强化对IE的兼容性,强制IE使用最新版标准模式渲染或者使用Chrome Frame渲染 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  3. viewport常见设置,一般适用于移动端。视口宽度设为理想宽度,禁止缩放。

    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
  4. meta三剑客

    <meta name="description" content="Tusi博客,专注大前端技术架构与分享,关注用户体验">
    <meta name="keyword" content="Tusi博客,web前端,nodejs全栈,响应式,用户体验">
    <meta name="author" content="Tusi">
  5. UC浏览器私有meta

    <!-- 横屏/竖屏 -->
    <meta name="screen-orientation" content="landscape|portrait">
    <!-- 全屏 -->
    <meta name="full-screen" content="yes">
    <!-- 缩放不出滚动条 -->
    <meta name="viewport" content="uc-fitscreen=yes|no">
    <!-- 排版,fitscreen简化页面,适合阅读省流量,standard模式和标准浏览器一致 -->
    <meta name="layoutmode" content="fitscreen|standard" 
    <!-- 夜间模式的启用和禁用 -->
    <meta name="nightmode" content="enable|disable"/>
    <!-- 强制图片显示 -->
    <meta name="imagemode" content="force"/>
    <!-- 强制图片显示,只作用于单图 -->
    <img data-original="..." show="force">
    <!-- 应用模式,默认全屏,禁止长按菜单,禁止手势,标准排版,以及强制图片显示。 -->
    <meta name="browsermode" content="application">
  6. QQ浏览器X5内核私有meta(现在微信内置浏览器的内核也是X5哦)

    <!-- 横屏/竖屏 -->
    <meta name="x5-orientation" content="landscape|portrait">
    <!-- 全屏 -->
    <meta name="x5-fullscreen" content="true">
    <!-- 应用模式 -->
    <meta name="x5-page-mode" content="app">
  7. 苹果机适配

    <!-- "添加到主屏幕“后,全屏显示 -->
    <meta name="apple-touch-fullscreen" content="yes">
    <!-- 隐藏菜单栏和状态栏,类似于应用模式 -->
    <meta name="apple-mobile-web-app-capable" content="yes|no">
    <!-- 设置状态栏颜色,貌似只有default白色,black黑色,black-translucent灰色半透明 -->
    <meta name=”apple-mobile-web-app-status-bar-style” content=black”>
    <!-- 取消电话号码识别,防止误触拨号 -->
    <meta name="format-detection" content="telephone=no">
  8. 其他优化和适配手段

    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 -->
    <meta name="HandheldFriendly" content="true">
    
    <!-- 微软的老式浏览器 -->
    <meta name="MobileOptimized" content="320">
    
    <!-- windows phone 点击无高光 -->
    <meta name="msapplication-tap-highlight" content="no">
    
    <!-- robots 用来告诉搜索机器人哪些页面需要被检索 -->
    <!-- index 搜索引擎抓取这个页面 -->
    <!-- noindex 搜索引擎不抓取这个页面 -->
    <!-- follow 抓取外链 -->
    <!-- nofollow 不抓取外链 -->
    <meta name="robots" content="index,follow">
    <meta name="robots" content="index,nofollow">
    <meta name="robots" content="noindex,follow">
    <meta name="robots" content="noindex,nofollow">
    
    <!-- referrer 控制http请求头的referer,暂时没想到什么实际应用场景 -->
    <!-- no-referrer 不发referer -->
    <!-- origin 只发送origin部分 -->
    <!-- no-referrer-when-downgrade 默认值,当目的地是先验安全的(https->https)则发送origin作为 referrer,但是当目的地是较不安全的(https->http)时则不发送referrer -->。
    <!-- origin-when-crossorigin 在同源请求下,发送完整的URL(不含查询参数),其他情况下则仅发送当前文档的origin -->
    <!-- unsafe-URL 在同源请求下,发送完整的URL(不含查询参数) -->
    <meta name="referrer" content="no-referrer">
    
    <!-- og: Open Graph Protocol,一种友好的配置,让自己的网站在社交网络分享中更得心应手,更多的配置可以去自行搜索 -->
    <!-- og:type 告诉SNS,我这是一个什么类型的网站 -->
    <meta property="og:type" content="article"/>
    <!-- og:title 告诉SNS,分享时告诉用户我这个网站的标题是什么,别自己瞎搞个标题 -->
    <meta property="og:title" content="Tusi博客"/>
    <meta property="og:url" content="https://blog.wbjiang.cn"/>
    <!-- og:image 缩略图 -->
    <meta property="og:image" content="/static/imgs/thumbnail.png"/>
    <meta property="og:description" content="专注于大前端技术架构与分享,关注用户体验"/>

首发链接


往期精彩:


扫一扫下方小程序码或搜索Tusi博客,即刻阅读最新文章!

Tusi博客

查看原文

Halz 赞了回答 · 2019-09-24

解决nuxt图片问题

图片放到static目录,改成这样

require('static/img/home.png')

关注 5 回答 4

Halz 赞了文章 · 2019-09-12

25个JavaScript代码简写技巧(上篇)


对于任何JavaScript开发人员来说,这篇文章很值得一读。这里记录了我多年来学习的JavaScript代码简洁写法,也给大家提供一些编码上的思考和取舍。

1. 三元(三目)运算符

如果只想在一行中编写if..else语句时,这是一个很好的节省代码的方式。

常规:

简写:

嵌套版三元运算:

2. 短路判断简写

将变量值分配给另一个变量时,您可能希望确保源变量不为null,undefined或为空。您可以编写带有多个条件的长 if 语句,也可以使用短路判断。

常规:

简写:

再来点示例,尝试一下:

请注意,如果将variable1设置为false或0,则赋值为bar。

3. 声明变量简写

常规:

简写:

4. If真值判断简写

这可能是微不足道的,但值得一提。在执行“if 检查”时,有时可以省略全等运算符。

常规:

简写:

注意:这两个例子并不完全相同,因为只要likeJavaScript是一个真值,检查就会通过。

这是另一个例子。如果a不等于true,那就做点什么吧。

常规:

简写:

5. For循环简写

如果您想要纯JavaScript并且不想依赖外部库(如jQuery或lodash),这个小技巧非常有用。

常规:

简写:

如果您只想访问索引,请执行以下操作:

如果要访问文字对象中的键,这也适用:

Array.forEach简写:

6. 短路判断赋值

如果预期参数为null或undefined,我们可以简单地使用短路逻辑运算符,只需一行代码即可完成相同的操作,而不是编写六行代码来分配默认值。

常规:

简写:

7. 十进制基本指数

你可能已经看过这个了。它本质上是一种编写没有尾随零的数字的奇特方式。例如,1e7实质上意味着1后跟7个零。它表示一个十进制基数(JavaScript解释为浮点类型)等于10,000,000。

常规:

简写:

8. 对象属性简写

在JavaScript中定义对象很简单。 ES6提供了一种更简单的方法来为对象分配属性。如果变量名称与对象键相同,则可以使用简写表示法。

常规:

简写:

9. 箭头函数简写

经典函数以简单的形式易于读写,但是一旦你开始将它们嵌套在其他函数调用中,它们往往会变得有点冗长和混乱。

常规:

简写:

重要的是要注意,箭头函数内部的 this 与常规函数的不同,因此这两个示例并不严格等效。有关详细信息,请参阅有关箭头函数语法的文章。

10. 隐式返回简写

Return 是我们经常使用的关键字,用于返回函数的最终结果。具有单个语句的箭头函数将隐式返回其执行结果(函数必须省略大括号({})以省略return关键字)。

要返回多行语句(例如对象),必须使用 () 而不是 {} 来包装函数体。这可确保将代码执行为单个语句。

常规:

简写:

11. 默认参数值

您可以使用if语句定义函数参数的默认值。在ES6中,您可以在函数声明本身中定义默认值。

常规:

简写:

12. 模板字符串

您是否厌倦了使用 '+' 将多个变量连接成一个字符串?有没有更简单的方法?如果你能够使用ES6,那么你很幸运。您需要做的就是使用反引号,并使用 ${} 来包含变量。

常规:

简写:

13. 解构赋值简写

如果您正在使用任何流行的Web框架,那么很有可能您将使用对象形式的数组或数据,在组件和API之间传递信息。数据对象到达组件后,您需要将其解构。

常规:

简写:

您甚至可以分配自己的变量名称,比如entity替换原来对象中的contact:


相关文章:

25个JavaScript代码简写技巧(下篇)

使用Array.isArray更好地检查数组

Vue.js应用性能优化一

Vue.js应用性能优化二

Vue.js应用性能优化三

如何使用Vue.js渲染JSON中定义的动态组件

构建Vue.js组件的10个技巧

查看原文

赞 42 收藏 35 评论 2

Halz 回答了问题 · 2019-09-05

解决Vue+elementUI分页后使用splice()删除某一行时出错

最后采用了一楼老哥的做法:用分页参数从后端获取

关注 3 回答 3

认证与成就

  • 获得 0 次点赞
  • 获得 8 枚徽章 获得 1 枚金徽章, 获得 2 枚银徽章, 获得 5 枚铜徽章

擅长技能
编辑

(゚∀゚ )
暂时没有

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2019-08-29
个人主页被 255 人浏览