Http 跨域造成首次 204, 第二次200(两次请求)

在跨域请求的时候, 会出现一次 204 请求, 返回 No Content. 之后会进行第二次请求, 返回真正的数据.

经过反复测试, 给出以下两种方案:

  1. 将跨域操作放在 nginx 后面使用 url 进行一次代理.
  2. 使用 application/x-www-form-urlencoded 替代 application/json

参考文档: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

使用 NodeJS 的部分测试代码:

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"name": "demo-cros-204",
"version": "1.0.2",
"main": "index.js",
"author": "OnO<corn.mars@ono.lol>",
"license": "MIT",
"dependencies": {
"@koa/cors": "^2.2.1",
"axios": "^0.18.0",
"koa": "^2.5.0",
"koa-body-parser": "^1.1.2",
"koa-bodyparser": "^4.2.0",
"koa-static": "^4.0.2",
"qs": "^6.5.1"
}
}

index.js

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
const Koa = require('koa');
const app = new Koa();

const cors = require('@koa/cors');
app.use(cors());

const bodyParser = require('koa-body-parser');
app.use(bodyParser());

app.use(require('koa-static')('public', {}));

app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(
`${ctx.method} ${ctx.url} - ${ms}ms\n Header: %j\n Body: %j\n Uri: %j\n Return: %j\n`,
ctx.header,
ctx.request.body,
ctx.query,
ctx.body
);
});

// response
app.use(ctx => {
ctx.body = 'Hello Koa';
});

app.listen(1224);
app.listen(1225);

public/demo-204.html 复现请求出现 204 情况

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="./axios.min.js"></script>
<script src="./qs.js"></script>
</head>
<body>
<script>
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios
.post('http://127.0.0.1:1225/', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
</script>
</body>
</html>

public/demo-200.html 使用 Content-Type 后解决两次请求, 直接拿到 200 后的结果

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script src="./axios.min.js"></script>
<script src="./qs.js"></script>
</head>
<body>
<script>
axios.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded';
axios
.post(
'http://127.0.0.1:1225/',
Qs.stringify({
firstName: 'Fred',
lastName: 'Flintstone'
})
)
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
</script>
</body>
</html>
Donate - Support to make this site better.
捐助 - 支持我让我做得更好.