解决ajax跨域几种方式
发生跨域问题的原因:
浏览器的限制,出于安全考虑。前台可以正常访问后台,浏览器多管闲事报跨域问题,但其实前台已经访问到后台了。
跨域,协议、域名、端口任何一个不一样浏览器就认为是跨域。
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跨域几种方式的更多相关文章
- 解决ajax跨域问题的一种方法
解决ajax跨域问题的一种方法 前后端分离经常用json来传输数据,比较常见的问题就有ajax跨域请求的错误问题,这里是我的一种解决方法: 在java中加入如下的注解类: import org.spr ...
- 如何解决ajax跨域问题(转)
由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题.本篇将讲述一个小白从遇到跨域不 ...
- 看小白如何解决ajax跨域问题
由于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决ajax的跨域问题.本篇将讲述一个小白从遇到跨域不知道 ...
- 如何解决ajax跨域问题
如何解决ajax跨域问题(转) 由 于此前很少写前端的代码(哈哈,不合格的程序员啊),最近项目中用到json作为系统间交互的手段,自然就伴随着众多ajax请求,随之而来的就是要解决 ajax的跨域问题 ...
- 如何解决Ajax跨域问题-1
如何解决Ajax跨域问题 最近在做AJAX调用C的问题,出现跨域问题,学习总结如下: 在做ajax读取数据的时候,经常会遇到ajax需要跨域的问题,但由于浏览器安全方面的限制,XMLHttpReque ...
- e3mall商城总结11之sso系统的分析、应用以及解决ajax跨域问题
说在前面的话 一.sso系统分析 什么是sso系统 SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次 ...
- 如何解决 ajax跨域被阻止 CORS 头缺少 'Access-Control-Allow-Origin'的问题?
已拦截跨源请求:同源策略禁止读取位于 http://192.168.1.72:8080/securityMonitor_TV/service/getTest 的远程资源. (原因:CORS 头缺少 ' ...
- 【前端_js】解决ajax跨域请求数据
1.ajax发送请求必须遵循同源策略,即请求方和相应方的协议头.域名.端口全部一样.只要三者有一个不一样都视为跨域,浏览器出于安全考虑不允许跨域访问. 解决ajax跨域访问的常用方法: a.使用jso ...
- 谷歌浏览器解决ajax跨域问题
在用mui和H5+做混合开发,会利用HBuildx去真机调试,可真机调试总有问题所在,懂得人自然懂,而我们直接打开页面显示的只有一个静态的页面,是获取不到数据的在这里我想说的不是代码中利用jsonp, ...
随机推荐
- 矩阵快速幂 求斐波那契第N项
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> us ...
- VMware虚拟机磁盘文件vmdk单文件转多文件相互转换
设置环境变量 set PATH=%PATH%;D:\Program Files (x86)\VMware\VMware Workstation echo %PATH% C:\Users\Admi ...
- Azure IoT 技术研究系列3
上篇博文中我们将模拟设备注册到Azure IoT Hub中:我们得到了设备的唯一标识. Azure IoT 技术研究系列2-设备注册到Azure IoT Hub 本文中我们继续深入研究,设备到云.云到 ...
- 7.docker私有registry
一.Docker Registry分类 Registry用于保存docker镜像,包括镜像的层次结构和元数据.都是基于https或者http工作的. 用户可自建Registry,也可使用官方的Dock ...
- Qt 打包release发布问题
除了使用depens查看exe依赖的dll,本文使用qt5.13自带的打包工具windeployqt.exe tips: demo.exe(x86) :C:\Qt\Qt5.12.3\5.12.3\ms ...
- vue组件学习(二)
父子组件之间的数据传递, 父传给子: 直接在组件上传,如:<count :number="2"> (冒号和不要冒号的区别,有冒号会自动转为相应的类型)在名为count的 ...
- 前端面试题常考&必考之--盒子模型和box-sizing(项目中经常使用)
主要考察width的值,包括padding\border\content等属性??? box-sizing属性是css3特有的哦*** 1>当box-sizing:content-box;时,跟 ...
- Sql server时间转时间long
DATEDIFF( S, '1970-01-01 00:00:00', a.endor_date ) - 8 * 60*60 ) actionTime, SELECT DATEADD(S,116070 ...
- 对拍程序 x
一.介绍 在做题或者正式比赛过程中总会把水题做水做乱,但因为样例有坑所以直接过了样例,然后拿去评测结果发现全WA.那如何在这种情况下检查自己程序或算法的正确性呢?对拍是一个简便省事的方案. 所谓“对拍 ...
- 洛谷p3956 棋盘(NOIP2017 t3)
在noip考场上本来以为只能骗暴力分,没想到最后A了: 本蒟蒻的做法比较简(zhi)单(zhang):记忆化深搜(考场上本来是想打广搜的,但我深搜稳一点就这样打了): 具体:每个点用一个f数组记录当前 ...