zoukankan      html  css  js  c++  java
  • JSON跨域问题总结

    一、跨域问题的原因:
    1 浏览器的检查
    2 跨域
    3 XMLHttpRequest请求
    二、跨域问题的解决:
    1 禁止浏览器检查:
    使用dos命令,在启动浏览器的时候,加一个参数:
    chrome --disable-web-security --user-data-dir=g: emp3
    2 JSONP:
    JSONP是什么:JSONP是一种协议
    JSONP解决跨域的时候后台代码需要改变吗:需要。
    需要加一个切面:@ControllerAdvice
    并且让这个类要继承AbstractJsonpResponseBodyAdvice
    并且重写构造方法JsonpAdvice(){
    super("callback");
    }

    JSONP的实现原理:
    JSONP的弊端:
    服务器需要改动代码
    只支持GET
    发送的不是XHR请求
    3 请求是跨域的与隐藏跨域:
    被调用方解决:
    服务器端实现:
    配置Filter:
    @Bean
    public FilterRegistrationBean registerFilter(){
    FilterRegistrationBean bean=new FilterRegistrationBean();
    bean.addUrlPattern("/*");
    bean.setFilter(new CrosFilter());
    }
    创建一个Filter:
    public class CrosFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException{
    }
    @Override
    public void doFilter(ServletRequest request,ServletResponse response,FilterChain filterChain)throws IOException, ServletException{
    HttpServletResponse res=(HttpServletResponse)response;
    res.addHeader("Access-Control-Allow-Origin","http://localhost:8081");
    res.addHeader("Access-Control-Allow-Methods","GET");
    res.addHeader("Access-Control-Allow-Headers","Content-Type");
    filterChain.doFilter(request,response);
    }
    }
    此处的res.addHeader("Access-Control-Allow-Origin","*");可以使用*来表示所有的域,方法也可以使用*来表示所有的方法。
    简单请求和非简单请求:
    工作中比较常见的【简单请求】:
    方法为:GET HEAD POST
    请求header里面:无自定义头、Content-Type为以下几种:
    text/plain
    multipart/form-data
    application/x-www-form-urlencoded
    工作中比较常见的【非简单请求】:
    put,delete方法的ajax请求
    发送json格式的ajax请求
    带自定义头的ajax请求
    OPTIONS预检命令:
    OPTIONS预检命令缓存:
    res.addHeader(“Access-Control-Max-Age”,”3600”);//表示在一小时内缓存这个OPTIONS信息,不用每次请求都请求两次。
    带Cookie的跨域问题:
    Origin必须是全匹配,不能使用*,必须指定域名;并且需要在Filter里面增加:
    res.addHeader(“Access-Control-Allow-Credentials”,”true”);
    带自定义头的跨域问题:
    被调用方-Nginx解决方案:
    1 配置虚拟文件vhost:在nginx的目录中创建一个文件夹,命名为vhost,并在nginx的配置文件中的最后一行中加入以下代码:include vhost/*.conf,将vhost中的.conf文件加载进来。
    2 在vhost文件夹下新建一个文件b.com.conf,使用nginx的语法,在该文件中加入以下内容:
    server{
    listen 80; //监听的端口
    server_name b.com;
    location /{
    proxy_pass http://localhost:8080/;
    }
    }
    此时访问b.com便可以代替之前的localhost:8080进行访问。
    3 继续在以上文件中添加:
    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配置:
    1 打开apache根目录下的conf文件夹下的httpd.conf文件,并搜索vhost,解开LoadModule vhost_alias_module modules/mod_vhost_alias.so
    2 继续搜索vhost,解开Include conf/extra/httpd-vhosts.conf
    3 打开conf文件夹下的extra文件夹下的httpd-vhosts.conf
    4 增加一个虚拟主机,复制一份,并且修改为以下内容:
    <VirtualHost *:80>
    ServerName b.com
    ErrorLog "logs/b.com-error.log"
    CustomLog "logs/b.com-access.log" common
    ProxyPass / http://localhost:8080/
    </VirtualHost>
    5 在httpd.conf文件中解开proxy模块:LoadModule proxy_module modules/mod_proxy.so (140行)
    6 在httpd.conf文件中解开proxy http模块:LoadModule proxy_http_module modules/mod_proxy_http.so
    7 进入apache的bin目录,双击httpd.exe文件,启动apache。
    8 在httpd-vhosts.conf文件中增加响应头:
    <VirtualHost *:80>
    ServerName b.com
    ErrorLog "logs/b.com-error.log"
    CustomLog "logs/b.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-Request-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-Max-Age "3600"
    Header always set Access-Control-Allow-Credentials "true"

    #处理预检命令OPTIONS,直接返回204
    RewriteEngine On
    RewriteCond %{REQUEST_METHOD} OPTIONS
    RewriteRule ^(.*)$ "/"[R=204,L]
    </VirtualHost>
    9 在httpd.conf文件中,解开headers模块:LoadModule headers_module modules/mod_headers.so
    10 在httpd.conf文件中,打开rewrite模块:LoadModule rewrite_module modules/mod_rewrite.so

    Spring框架的跨域解决:
    在控制器中使用@CrossOrigin注解
    调用方解决-隐藏跨域:
    1 在hosts文件中,增加一个虚拟域名:127.0.0.1 b.com a.com
    2 在nginx的vhosts文件夹中新建一个a.com.conf,打开:
    server{
    listen 80;
    server_name a.com;
    location /{
    proxy_pass http://localhost:8081/;
    }
    location /ajaxserver{
    proxy_pass http://localhost:8080/test/;
    }
    }
  • 相关阅读:
    pyhton 线程锁
    python 守护线程
    python 线程
    python 判断文件的字符编码
    python 进程管道
    python 进程池
    webpack学习(一)起步安装
    最近特别喜欢的一首歌
    你真的了解回流和重绘吗?
    你了解SEO中的时效性吗?
  • 原文地址:https://www.cnblogs.com/laowangc/p/8869989.html
Copyright © 2011-2022 走看看