ajax遇到的跨域问题
Posted zerotop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ajax遇到的跨域问题相关的知识,希望对你有一定的参考价值。
### 简述
在使用通过ajax发送请求时经常会出现跨域问题问题
以下几个场景是从遇到跨域问题,到一步步解决的过程
三种解决方案:
1.jsonp:
jsonp方案需要后端配合,所以最好使用node将数据转发到后端
然后再通过拼接jsonp的callback函数
通过服务器端转发请求也可以
2.设置代理:
代理暂时使用node中间件或者可以配置nigix代理
3.后端允许跨域:
cors跨域资源共享
这个时候可以用node代理解决
### 场景1解决方案
直接使用node后端设置代理
```
var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();
```
这样可以将: http://xxx.xxx.xxx.xx:8088/api/info
请求全部转发到:http://xxx.xxx.xxx.xx:8888/info
### 场景2
每次请求都会导致重新创建session,session无法存储数据
导致登录后,显示未登录状态
这时候需要设置xhrFields:{withCredentials:true},
```
$.ajax ({
type: "get",
url : "http://xxx.xxx.xxx.xx:8888/account/userinfo",
xhrFields:{withCredentials:true},
dataType: "json",
success: function (json) {
console.log(json)
},
error: function (err) {
console.log(err)
}
})
```
这时候会导致 Access-Control-Allow-Origin 一定要与请求的一致,
比如前端请求: origin:null
后端返回header: Access-Control-Allow-Origin:null
### 场景2解决方案
针对场景2,可以在后端设置允许跨域
```
res.addHeader("Access-Control-Allow-Origin", req.getHeader(origin));
res.setHeader("Access-Control-Allow-Credentials", "true");
```
上面这种设置理论上不是很合理
我们最好通过设置代理去解决这个问题
### 场景3
有很多时候,我们会向后端传送不同类型的数据
比如ajax默认:application/x-www-form-urlencoded
这个时候如果你想要传json形式的文件,那就需要制定传送的内容
```
var data = { "name": "type" }
$.ajax ({
type: "post",
url : "http://xxx.xxx.xxx.xx:8088/query",
xhrFields:{withCredentials:true},
dataType: "json",
contentType:"application/json",
data: data,
success: function (json) {
console.log(json)
},
error: function (err) {
console.log(err)
}
})
```
恭喜您又解锁了一个新的错误:
Failed to load http://xxx.xxx.xxx.xx:8088/query: Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
### 场景3解决方案
在预检响应中,Access-Control-Allow-Header不允许使用字段Content-Type
这个是什么意思呢,就是在请求时候,会先向后端请求一下,看看是否允许自定义头信息
"Access-Control-Allow-Headers": "Content-Type, X-Requested-With"
### 场景4
此时我们已经解决了大部分问题
在如果向node后端发送请求时候
我们会使用querystring去取post发送的数据
但是你会惊奇的发现第一次请求可能取不到数据
等到第二次再去取得时候,发现这个时候可以取到值
### 场景4解决方案
所以我们需要如果是post请求时,需要在第二次
req.on('end', function () {}); 的时候拿到post的数据
### 后记
node中出现如下异常:
Header "%s" value must not be undefined
```
var origin = typeof(req.headers.origin) == "undefined" ? "*" : req.headers.origin
"Access-Control-Allow-Origin": origin,
```
附一份node端header:
var origin = typeof(req.headers.origin) == "undefined" ? "*" : req.headers.origin;
res.writeHead(200, {
"Access-Control-Allow-Origin": origin,
"Access-Control-Allow-Credentials": true,
"Access-Control-Allow-Headers": "Content-Type, X-Requested-With",
"Access-Control-Allow-Methods": "PUT,POST,GET,DELETE,OPTIONS",
"X-Powered-By": ' 3.2.1',
"Content-Type": "application/json;charset=utf-8"
});
致此我们将此次遇到的问题全部解释清楚
如果想看更详细的解释,可以点击原文链接
希望可以互相帮助共同提升。
以上是关于ajax遇到的跨域问题的主要内容,如果未能解决你的问题,请参考以下文章
Jquery:使用 laravel 的跨域 ajax 'POST'