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遇到的跨域问题的主要内容,如果未能解决你的问题,请参考以下文章

关于AJAX的跨域问题

Jquery:使用 laravel 的跨域 ajax 'POST'

带有 jquery.ajax() 的跨域“授权”标头

chrome中的跨域ajax POST

jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求

如何解决ajax跨域问题(转)