ta_shuo


  • 首页

  • 分类

  • 归档

  • 标签

  • 公益404
ta_shuo

Laravel跨域处理

发表于 2020-06-05 | 分类于 php , laravel | | 阅读次数

背景

在前后端分离的应用中,需要使用CORS完成跨域访问。在CORS中发送 非简单请求时,前端会发一个请求方式为OPTIONS的预请求,前端只有收到服务器对这个OPTIONS请求的正确响应,才会发送正常的请求,否则将抛出跨域相关的错误。

跨域

可实现跨域的方式
  • JSONP
  • CORS
  • Flash
  • 服务器中转

比较常用的是 JSONP和 CORS,而后者相对前者来说有更方便实用:

  1. JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
  2. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

此文暂不介绍jsonp

CORS

CORS是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源。而这种访问是被同源策略所禁止的。CORS系统定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。
使用 CORS的方式非常简单,但是需要同时对前端和服务器端做相应处理。

客户端使用XmlHttpRequest发起Ajax请求,当前绝大部分浏览器已经支持CORS方式,且主流浏览器均提供了对跨域资源共享的支持。

如上所述,接着只需在服务端配置可允许跨域的header即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php # TestController.php
class TestController
{
public function __construct()
{
// 跨域头
header('Access-Control-Allow-Origin: *');
}
public function test()
{
echo 'test';
}
}

阅读全文 »
ta_shuo

Go by Example - Sorting

发表于 2019-04-13 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Sorting

golang的sort包可以对内置类型和用户定义的类型进行排序操作,接下来我们先看下内置类型。

阅读全文 »
ta_shuo

2018年度总结

发表于 2019-01-06 | 分类于 生活 | | 阅读次数

未经审视的生活是不值得过的 - 苏格拉底

生命是一团欲望,欲望不能满足便痛苦,满足便无聊,人生就在痛苦和无聊之间摇摆 - 叔本华

上周五刚卷铺盖滚出了入职不满四个多月的厂子,如今写起字来不免悲凉,只希望接下来文思泉涌时莫泪洒键盘,笔记本给整坏了,恐怕一时半会都没钱修理了。


干过的事儿

书

  • 西西弗神话-加缪全集:第五卷 ✭✭✭✭✭
  • 博尔赫斯,口述 ✭✭✭✭✭
  • 杜撰集 ✭✭✭✭✭
  • 千年繁华-京都的街巷人生 ✭✭✭✭
  • 永恒史 ✭✭✭✭
  • 解忧杂货店 ✭✭✭✭
  • 就喜欢你看不惯我又干不掉我的样子3 ✭✭✭✭
  • 十一种孤独 Eleven Kinds of Loneliness ✭✭✭✭✭
  • 假面山庄 ✭✭✭✭
  • 漫长的告别 ✭✭✭✭
  • 北方的空地 ✭✭✭✭✭
  • 情人 ✭✭✭✭
  • 广岛之恋 ✭✭✭✭
  • 再见,宝贝 Farewell, My Lovely ✭✭✭✭
  • 湖底女人 The Lady in the Lake ✭✭✭✭
  • 傅译巴尔扎克代表作1 ✭✭✭✭✭
  • 傅译巴尔扎克代表作2 ✭✭✭✭✭
  • 傅译巴尔扎克代表作3 ✭✭✭✭✭
  • 高窗 The High Window ✭✭✭✭
  • 房思琪的初恋乐园 ✭✭✭✭✭
  • 看不见的城市 Le città invisibili ✭✭✭✭✭
  • 月亮和六便士 ✭✭✭✭✭
  • 面纱 ✭✭✭✭
  • 简爱 ✭✭✭✭
  • 艽野尘梦 ✭✭✭✭✭
  • 1Q84 BOOK 1 ✭✭✭✭
  • 1Q84 BOOK 2 ✭✭✭✭
  • 1Q84 BOOK 3 ✭✭✭✭
  • 一桩事先张扬的凶杀案 ✭✭✭✭
  • 你的第一本哲学书 What Does it All Mean? ✭✭✭✭✭
  • 哲学家们都干了些什么 ✭✭✭✭
  • 荒原狼 ✭✭✭✭✭
  • 爱你就像爱生命 ✭✭✭✭
  • 在路上 On the Road ✭✭✭✭
  • 三个火枪手 ✭✭✭
阅读全文 »
ta_shuo

Go by Example - Stateful Goroutines

发表于 2018-02-06 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Stateful Goroutines

未完待续…

ta_shuo

Go by Example - Mutexes

发表于 2017-12-13 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Mutexes

在前面的示例中我们看到如何通过原子操作来管理简单的计数器。对于更复杂的状态,我们可以使用互斥锁在多个goroutine中安全地访问数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main
import (
"fmt"
"math/rand"
"sync"
"sync/atomic"
"time"
)
func main() {
// 此处状态是一个map
var state = make(map[int]int)
// 初始化锁
var mutex = &sync.Mutex{}
// 定义两个变量用于追踪读和写的总次数
var readOps uint64 = 0
var writeOps uint64 = 0
// 启动100个goroutines读取状态值,每个goroutine耗时1毫秒
for r := 0; r < 100; r++ {
go func() {
total := 0
for {
// 随机读取状态的某一个值
// 1、加锁
// 2、读取
// 3、解锁
key := rand.Intn(5)
mutex.Lock()
total += state[key]
mutex.Unlock()
// 次数自增1
atomic.AddUint64(&readOps, 1)
// 两次读取之间睡眠1毫秒
time.Sleep(time.Millisecond)
}
}()
}
// 同上,启动10个goroutines模拟写操作
// 随机给状态赋值,写操作次数自增1,睡眠1毫秒
for w := 0; w < 10; w++ {
go func() {
for {
key := rand.Intn(5)
val := rand.Intn(100)
mutex.Lock()
state[key] = val
mutex.Unlock()
atomic.AddUint64(&writeOps, 1)
time.Sleep(time.Millisecond)
}
}()
}
// 睡眠一秒等待读写操作
// 打印出读写次数
time.Sleep(time.Second)
readOpsFinal := atomic.LoadUint64(&readOps)
fmt.Println("readOps:", readOpsFinal)
writeOpsFinal := atomic.LoadUint64(&writeOps)
fmt.Println("writeOps:", writeOpsFinal)
// 使用锁取出最后的状态值
mutex.Lock()
fmt.Println("state:", state)
mutex.Unlock()
}
阅读全文 »
ta_shuo

Go by Example - Atomic Counters

发表于 2017-11-28 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Atomic Counters

golang管理状态的主要机制是通过channel的通信,可以通过之前的worker pools的例子看到。还有一些其他的管理状态的方式,这次我们探究一下sync/atomic包中的可以被多个goroutine访问的atomic counters.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package main
import "fmt"
import "time"
import "sync/atomic"
func main() {
// 使用无符号正整数用来表示计数
var ops uint64 = 0
// 为了模拟并发更新,我们启动50个goroutine,每个goroutine对计数自增1,大概1毫秒的耗时
for i := 0; i < 50; i++ {
go func() {
for {
// 使用AddUint64进行原子性的递增操作,将变量的地址作为参数传给该函数
atomic.AddUint64(&ops, 1)
// 睡眠1毫秒,模拟耗时
time.Sleep(time.Millisecond)
}
}()
}
// 睡眠1秒进行若干累加操作
time.Sleep(time.Second)
// 由于计数器可能正在被其他goroutine进行累加操作,为了安全的获取计数值,我们通过LoadUint64函数获取计数器的一个拷贝,将计数器的内存地址给该函数
opsFinal := atomic.LoadUint64(&ops)
fmt.Println("ops: ", opsFinal)
}
1
2
tashuo:golang ta_shuo$ go run atomic-counter.go
ops: 41280

运行该程序,通过返回值可得知计数器累加了大概40000多次

原文链接:Go by Example: Atomic Counters

ta_shuo

Go by Example - Rate Limiting

发表于 2017-11-24 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Rate Limiting

限速是控制资源利用率和维持服务质量的一种重要机制。golang通过goroutines、channels和tickers优雅的支持限速。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main
import "fmt"
import "time"
func main() {
// 首先来看下基本的限速功能
// 假设我们想限制对请求的处理
// 我们将从同一个管道中提供这样的请求
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)
// 该管道每200毫秒接收一个值
// 这个是我们限速的核心
limiter := time.Tick(time.Millisecond * 200)
// 通过处理每个请求时管道接收值的阻塞,我们限制每200毫秒只处理一个请求
for req := range requests {
<-limiter
fmt.Println("request", req, time.Now())
}
// 某些时候可能希望在保持整体限速规则下允许少量的请求不受限制
// 可以通过含有缓冲区的管道来实现
// burstyLimiter管道可以使同时处理的请求达到3个
burstyLimiter := make(chan time.Time, 3)
for i := 0; i < 3; i++ {
burstyLimiter <- time.Now()
}
// 每200毫秒发送给burstyLimiter管道一个值
go func() {
for t := range time.Tick(time.Millisecond * 200) {
burstyLimiter <- t
}
}()
// 模拟5个新的请求,前三个请求由于burstyLimiter管道缓冲区的处理可以突破200毫秒的限制
burstyRequests := make(chan int, 5)
for i := 1; i <= 5; i++ {
burstyRequests <- i
}
close(burstyRequests)
for req := range burstyRequests {
<-burstyLimiter
fmt.Println("request", req, time.Now())
}
}
1
2
3
4
5
6
7
8
9
10
11
tashuo:golang ta_shuo$ go run rate-limiting.go
request 1 2017-11-24 15:45:04.641607273 +0800 CST
request 2 2017-11-24 15:45:04.838581623 +0800 CST
request 3 2017-11-24 15:45:05.040839234 +0800 CST
request 4 2017-11-24 15:45:05.241695212 +0800 CST
request 5 2017-11-24 15:45:05.441367122 +0800 CST
request 1 2017-11-24 15:45:05.441428032 +0800 CST
request 2 2017-11-24 15:45:05.441435722 +0800 CST
request 3 2017-11-24 15:45:05.441440602 +0800 CST
request 4 2017-11-24 15:45:05.641538132 +0800 CST
request 5 2017-11-24 15:45:05.84206538 +0800 CST

前5个请求跟预期一样是每200秒处理一个,后面5个请求中的前3个并没有被200毫秒的规则限制到。

原文链接:Go by Example: Rate Limiting

ta_shuo

Go by Example - Worker Pools

发表于 2017-11-24 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Worker Pools

这节探索如何使用goroutine和channel实现工作池的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package main
import "fmt"
import "time"
// 这个是工作进程,用来执行并发的任务
// 每个进程都会从管道jobs接受工作,并且将相应发送至管道results
// 每个工作我们都会睡眠一秒用以模拟一项耗时的任务
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j)
time.Sleep(time.Second)
fmt.Println("worker", id, "finished job", j)
results <- j * 2
}
}
func main() {
// 初始化两个管道用以给工作进程分配任务及接收结果
jobs := make(chan int, 100)
results := make(chan int, 100)
// 启动三个工作进程
// 此时它们是阻塞的,因为管道jobs是空的
for w:= 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// 初始化5个任务
// 关闭管道jobs,标识没有多余的任务了
for j:= 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// 收集所有任务的结果
for a := 1; a <= 5; a++ {
<-results
}
}
1
2
3
4
5
6
7
8
9
10
11
tashuo:golang ta_shuo$ go run worker-pool.go
worker 3 started job 1
worker 2 started job 3
worker 1 started job 2
worker 3 finished job 1
worker 3 started job 4
worker 2 finished job 3
worker 1 finished job 2
worker 2 started job 5
worker 2 finished job 5
worker 3 finished job 4

通过输出可以看出5个任务被多个工作进程执行。程序只消耗了2秒多而不是5秒,是因为所有的任务被3个工作进程并发处理。

原文链接:Go by Example: Worker Pools

ta_shuo

Go by Example - Tickers

发表于 2017-09-06 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Tickers

Timer是当你想要在未来某个时间只执行一次某个事件时使用,而ticker可以用来以一定时间间隔重复执行一个事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main
import "time"
import "fmt"
func main() {
// Ticker跟Timer是类似的机制:使用管道来通信
// 下面示例中我们使用内置的for-range语句对于每500毫秒接收到一个的值进行迭代处理
ticker := time.NewTicker(time.Millisecond * 500)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()
// 跟Timer一样,Ticker也可以被停止
// 当Ticker取消时,其相应的管道不会再接收到值
// 该示例中我们在1600毫秒后停止
time.Sleep(time.Millisecond * 1600)
ticker.Stop()
fmt.Println("Ticker stoped")
}
1
2
3
4
5
tashuo:golang ta_shuo$ go run ticker.go
Tick at 2017-09-06 11:47:35.512980179 +0800 CST
Tick at 2017-09-06 11:47:36.012186259 +0800 CST
Tick at 2017-09-06 11:47:36.515210336 +0800 CST
Ticker stoped

在执行1600毫秒被停止时Ticker 500毫秒的间隔应该已经重复执行了三次

原文链接:Go by Example: Tickers

ta_shuo

Go by Example - Timers

发表于 2017-09-06 | 分类于 golang , 笔记 | | 阅读次数

翻译自 https://gobyexample.com/

Go by Example

Go is an open source programming language designed for building simple, fast, and reliable software.

Go by Example is a hands-on introduction to Go using annotated example programs. Check out the first example or browse the full list below.

Go by Example: Timers

我们经常希望golang代码在未来某个时间点执行或者以一定的时间间隔重复执行,golang内置的timer和ticker功能可以轻松实现这两种工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package main
import "time"
func main() {
// Timer类似于未来一个独立的事件,可以告诉它你要等待多久,它会提供一个管道用来在时间点到时发出通知
// 该例中会等待2秒
timer1 := time.NewTimer(time.Second * 2)
// <- timer1.C会一直阻塞直到时间过期管道发送出一个值
<- timer1.C
println("Timer1 expired")
// 如果只是想等待一段时间,可以使用`time.Sleep`
// 但使用timer你可以在时间到期前取消,这个也是Sleep做不到的
timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
println("Timer2 expired")
}()
// 使用Stop来取消timer
stop2 := timer2.Stop()
if stop2 {
println("Timer2 stopped")
}
}
1
2
3
tashuo:golang ta_shuo$ go run timer.go
Timer1 expired
Timer2 stopped

第一个timer会在2秒后过期,但是第二个timer在过期前被Stop,所以没有过期

原文链接:Go by Example: Timers

12…6
ta_shuo

ta_shuo

我们坐着不同的井 望着同样的天

56 日志
15 分类
17 标签
© 2020 ta_shuo