发生跨域问题的原因:

  • 浏览器的限制,出于安全考虑。前台可以正常访问后台,浏览器多管闲事报跨域问题,但其实前台已经访问到后台了。

  • 跨域,协议、域名、端口任何一个不一样浏览器就认为是跨域。

  • XHR(XMLHttpRequest)请求,因为ajax是XHR请求,浏览器就会捕捉跨域问题。

简单请求和非简单请求:

  • 简单请求 GET HEAD POST,请求header里面:无自定义头,Content-Type为以下几种:text/plain,multipart/form-data,application/x-www-form-urlencoded。

  • 非简单请求 put,delete方法的ajax请求,发送json格式的ajax请求,带自定义头的ajax请求。

解决思路:

  • 让浏览器不做限制,指定参数,让浏览器不做校验,但该方法不太合理,它需要每个人都去做改动。

  • 不要发出XHR请求,这样就算是跨域,浏览器也不会报错,解决方案是JSONP,通过动态创建一个script,通过script发出请求。

  • 在跨域的角度:一种是被调用方修改代码,加上字段,告诉浏览器,支持跨域,支持调用。

  • 通过nginx代理方式,在a域名里面的的请求地址使用代理指定到b域名。

跨域解决方案:

  • 被调用方解决:在请求响应头增加指定字段,告诉浏览器允许调用。这种解决方案的请求是直接从浏览器发送的。(服务器端实现、NGINX配置Apache配置)。

  • 调用方解决:这是隐藏跨域的解决法案。这种跨域请求不是直接从浏览器发送的,而是从中间的http服务器转发过去的。

设置浏览器不做限制:

  • 可以使用everyting软件搜索浏览器的全路径,使用dos切换到此路径下 cd C:\Users\Administrator\AppData\Local\Google\Chrome\Application

  • 输入 chrome --disable-web-security --user-data-dir=g:\temp3(g磁盘 temp3数据存储文件可随便创建)。

使用jsonp解决:

  • Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP )呢?这是因为同源策略。同源策略,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。

  • 前端ajax方法请求设置 dataType: "jsonp", jsonp: "callback", cache: true

  • 后台需要增加JsonpAdvice 类

  • jsonp只支持GET
  • 服务器需要改动代码
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
// TODO Auto-generated constructor stub
// 这的名称需要和ajax中jsonp: "callback"设置的一样
super("callback");
}
}
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>跨域</title>
<script src="jquery-1.11.3.js"></script>
<link rel="stylesheet" type="text/css" href="jasmine-2.8.0/jasmine.css">
<script src="jasmine-2.8.0/jasmine.js"></script>
<script src="jasmine-2.8.0/jasmine-html.js"></script>
<script src="jasmine-2.8.0/boot.js"></script>
</head> <body>
<script>
function get1() {
$.getJSON("http://localhost:8080/test/get1").then(function (result) {
console.log(result);
});
}
// 每一个测试用例的超时时间
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;
// 请求的接口的前缀 // http://localhost:8080/test
var base = "/ajaxserverapache";
//测试模块
describe("跨域", function () {// 测试方法
it("jsonp请求", function (done) {
// 服务器返回的结果
var result;
$.ajax({
url: base + "/get1",
dataType: "jsonp",
jsonp: "callback",
cache: true,
success: function (json) {
result = json;
}
});
// 由于是异步请求,需要使用setTimeout来校验
setTimeout(function () {
expect(result).toEqual({
"data": "get1 ok"
}); // 校验完成,通知jasmine框架
done();
}, 100);
});
});
</script>
</body> </html>

filter解决方案(被调用方):

  • 在springBoot启动类中设置filter类过滤

  • 设置具体的过滤参数信息

@SpringBootApplication
public class AjaxserverApplication {
public static void main(String[] args) {
SpringApplication.run(AjaxserverApplication.class, args);
} @Bean
public FilterRegistrationBean registerFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.addUrlPatterns("/*");
// 设置自定义的filter类
bean.setFilter(new CrosFilter());
return bean;
}
}
public class CrosFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
} @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletResponse res = (HttpServletResponse) response; HttpServletRequest req = (HttpServletRequest) request; String origin = req.getHeader("Origin"); if (!org.springframework.util.StringUtils.isEmpty(origin)) {
//带cookie的时候,origin必须是全匹配,不能使用*
res.addHeader("Access-Control-Allow-Origin", origin);
} res.addHeader("Access-Control-Allow-Methods", "*");
String headers = req.getHeader("Access-Control-Request-Headers"); // 支持所有自定义头
if (!org.springframework.util.StringUtils.isEmpty(headers)) {
res.addHeader("Access-Control-Allow-Headers", headers);
}
     // 设置预检命令一小时内不需要再发送
res.addHeader("Access-Control-Max-Age", "3600");
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
} @Override
public void destroy() {
// TODO Auto-generated method stub
}
}

nginx解决方案(被调用方):

  • 在nginx文件中创建一个挂载文件夹vhost(创建a.conf配置文件)

  • 在nginx.conf配置文件中引入vhost文件夹下conf结尾的配置文件    include vhost/*.conf;

  • 配置如下(nginx -t检测配置文件是否正确   之后重载配置文件 nginx -s reload)
server{
listen 80;
server_name a.com; location /{
proxy_pass http://localhost:8080/; add_header Access_Control-Allow-Methods *;
add_header Access_Control-Max-Age 3600;
add_header Access_Control-Allow-Credentials true;
add_header Access_Control-Allow-Origin $http_origin;
add_header Access_Control-Allow-Headers
$http_access_control_request_headers; if ($request_method = OPTIONS){
# 判断是否是预检命令
return 200;
}
}
}

Apache服务解决:

  • 打开Apache24\conf\httpd.conf配置文件

  • 放开注释的配置:

  • LoadModule vhost_alias_module modules/mod_vhost_alias.so

  • Include conf/extra/httpd-vhosts.conf

  • LoadModule proxy_module modules/mod_proxy.so

  • LoadModule proxy_http_module modules/mod_proxy_http.so

  • LoadModule headers_module modules/mod_headers.so

  • LoadModule rewrite_module modules/mod_rewrite.so

  • 打开Apache24\conf\extra\httpd-vhosts.conf配置文件,在最下边添加配置

  • 重启服务
<VirtualHost *:80>
ServerName a.com
ErrorLog "logs/a.com-error.log"
CustomLog "logs/a.com-access.log" common
ProxyPass /http://localhost:8080/ # 把请求头的origin值返回到Access-Control-Allow-Origin字段
Header always set Access-Control-Allow-Origin 'expr=%{req:origin}' # 把请求头的Access-Control-Allow-Headers值返回到Access-Control-Allow-Headers字段
Header always set Access-Control-Allow-Headers "expr=%{req:Access-Control-Request-Headers}" Header always set Access-Control-Allow-Methods "*"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Max-Age "3600" #处理预检命令
RewriteEngine On
RewriteCond %{REQUEST_METHOD}OPTIONS
RewriteRule ^(.*)$"/" [R=204,L]
</VirtualHost>

spring解决:

  • String 框架解决方案: @CrossOrigin  注解添加类上面

被调用方隐藏跨域解决Apache服务解决:

  打开Apache24\conf\extra\httpd-vhosts.conf配置文件,在最下边添加配置

重启服务

<VirtualHost *:80>
ServerName a.com
ErrorLog "logs/a.com-error.log"
CustomLog "logs/a.com-access.log" common #被调用方接口
ProxyPass /ajaxserverapache http://localhost:8080/test
#调用方
ProxyPass /http://localhost:8081/
</VirtualHost>

被调用方隐藏跨域解决nginx:

  • 在nginx文件中创建一个挂载文件夹vhost(创建a.conf配置文件)

  • 在nginx.conf配置文件中引入vhost文件夹下conf结尾的配置文件    include vhost/*.conf;

  • 页面中接口访问前缀替换成下配置的相对路径/ajaxserver

  • 配置如下(nginx -t检测配置文件是否正确   之后重载配置文件 nginx -s reload)

server{
listen 80;
server_name a.com; location /{
# 调用方
proxy_pass http://localhost:8081/;
} location /ajaxserver{
# 被调用方接口
proxy_pass http://localhost:8080/test;
}
}

解决ajax跨域几种方式的更多相关文章

  1. 解决ajax跨域问题的一种方法

    解决ajax跨域问题的一种方法 前后端分离经常用json来传输数据,比较常见的问题就有ajax跨域请求的错误问题,这里是我的一种解决方法: 在java中加入如下的注解类: import org.spr ...

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

    由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题.本篇将讲述一个小白从遇到跨域不 ...

  3. 看小白如何解决ajax跨域问题

    由于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决ajax的跨域问题.本篇将讲述一个小白从遇到跨域不知道 ...

  4. 如何解决ajax跨域问题

    如何解决ajax跨域问题(转) 由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题 ...

  5. 如何解决Ajax跨域问题-1

    如何解决Ajax跨域问题 最近在做AJAX调用C的问题,出现跨域问题,学习总结如下: 在做ajax读取数据的时候,经常会遇到ajax需要跨域的问题,但由于浏览器安全方面的限制,XMLHttpReque ...

  6. e3mall商城总结11之sso系统的分析、应用以及解决ajax跨域问题

    说在前面的话 一.sso系统分析 什么是sso系统 SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次 ...

  7. 如何解决 ajax跨域被阻止 CORS 头缺少 'Access-Control-Allow-Origin'的问题?

    已拦截跨源请求:同源策略禁止读取位于 http://192.168.1.72:8080/securityMonitor_TV/service/getTest 的远程资源. (原因:CORS 头缺少 ' ...

  8. 【前端_js】解决ajax跨域请求数据

    1.ajax发送请求必须遵循同源策略,即请求方和相应方的协议头.域名.端口全部一样.只要三者有一个不一样都视为跨域,浏览器出于安全考虑不允许跨域访问. 解决ajax跨域访问的常用方法: a.使用jso ...

  9. 谷歌浏览器解决ajax跨域问题

    在用mui和H5+做混合开发,会利用HBuildx去真机调试,可真机调试总有问题所在,懂得人自然懂,而我们直接打开页面显示的只有一个静态的页面,是获取不到数据的在这里我想说的不是代码中利用jsonp, ...

随机推荐

  1. mongo 数据库操作

    启动和关闭数据库 启动 # mongodb 默认使用执行 mongod 命令所处的盘的根目录下  /data/db 作为自己的数据存储目录 #   所以在第一次执行该命令之前先自己动手新建一个  /d ...

  2. PAT Advanced 1006 Sign In and Sign Out (25 分)

    At the beginning of every day, the first person who signs in the computer room will unlock the door, ...

  3. Linux之文件属性、权限

    Linux中的3种身份:1. owner(文件所有者) 2. group(用户组) 3. others(其他) Linux中的3中权限:1. r(可读) 2. w(可写) 3. x(可执行) * 所有 ...

  4. rev 反向输出文件内容

    1.命令功能 rev 按行反向输出文件内容 2.语法格式 rev  file 3.使用范例 [root@localhost ~]# echo {a..k} >> test [root@lo ...

  5. 每日一蠢 .kettle 下的kettle.properties文件内配置的内容不能被识别

    昨天装封装好的ETL 工具  窝将环境变量中的KETTLE_HOME删除了, 结果 .kettle 下的kettle.properties文件内配置的内容不能被识别 can't parse argum ...

  6. Thymeleaf静态资源引入方式及公共页面代码抽取

    静态资源引入 Thymeleaf模板引擎url问题,要用如下的方式写,确保在任何情况下都能访问到 <!-- Bootstrap core CSS --> <link href=&qu ...

  7. 接口测试的一些FAQ

    近期在学习接口测试,总会有很多问题,故把前任给的经验做个记录下. 1,测试一条delete接口,delete请求后要检验什么内容: 原来删除有分为:物理删除,删除资源,删除关系,软删除 一般delet ...

  8. 【leetcode】494. Target Sum

    题目如下: 解题思路:这题可以用动态规划来做.记dp[i][j] = x,表示使用nums的第0个到第i个之间的所有元素得到数值j有x种方法,那么很容易得到递推关系式,dp[i][j] = dp[i- ...

  9. [HG]walk 题解

    前言 学长博客划水,抄题解,差评. 于是我来重新写一篇正常的题解,虽然解法跟标程不一样,但是复杂度是一样的. 题面 题目描述 在比特镇一共有\(n\)个街区,编号依次为\(1\)到\(n\),它们之间 ...

  10. HDU 6616 Divide the Stones

    目录 题面 中文题意 比赛惨状 我的走不通的思路 \(m\)是偶数的情况 \(m\)是奇数的情况 题解的思路 另一些思路 源代码 题面 Time limit 3000 ms Memory limit ...