发生跨域问题的原因:

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

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

  • 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. CRMEasy知识库点击无法弹出窗体问题

    丢失控件   MSDATLST.OCX 将此控件放在路径下    C:\Windows\System32 并进行注册,具体方法为: 打开控件方式选择   C:\Windows\System32\reg ...

  2. 魔咒词典 HDU - 1880 (字符串hash 单hash转int或者 双hash )

    哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. 给你一部魔咒词 ...

  3. vecto容器中一些没有注意到的地方

    vector容器 vectoor是一个单口容器. vector动态增长的基本原理 当插入新元素的时候,如果空间不足,那么vector会重新申请更大的一块内存空间,将原空间数据拷贝到新空间,释放旧空间的 ...

  4. c++ 创建线程用CreateThread后,线程直接就开始执行了吗

    //CreateThread函数的参数原型如下 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD SIZE_T ...

  5. 【LuoguP2792 】[JSOI2008]小店购物(最小树形图)

    题目链接 题目描述 小店的优惠方案十分简单有趣: 一次消费过程中,如您在本店购买了精制油的话,您购买香皂时就可以享受2.00元/块的优惠价:如果您在本店购买了香皂的话,您购买可乐时就可以享受1.50元 ...

  6. 详解Spring MVC 集成EHCache缓存_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 废话少说,直接上代码: ehcache.xml 文件 <?xml version="1.0" ...

  7. SpringCloud学习系列-构建部门微服务提供者Module

    1.新建microservicecloud-provider-dept-8001 2.POM <project xmlns="http://maven.apache.org/POM/4 ...

  8. Rosetta Stone 不在C盘安装步骤

    本文出自:http://www.cnblogs.com/2186009311CFF/p/7500637.html Rosetta Stone默认安装在C盘的,很不好,故找到次解决方案: 总体就是移动文 ...

  9. 完美解决linux不能编辑sshd_cofig和实现xshell远程连接的问题

    第一步:我们使用命令行vim /etc/ssh/sshd_config   执行修改,强制保持  :wq!  系统不让我们修改这个文件 "/etc/ssh/sshd_config" ...

  10. PHP入门培训教程 一个漂亮的PHP验证码

    如何写一个漂亮的PHP验证码?兄弟连PHP培训 小编分享一段代码给大家: <?php class Imagecode{ private $width ; private $height; pri ...