AJAX跨域问题解析

AJAX跨域问题

为什么会发生AJAX跨域

浏览器限制

浏览器禁止检查跨域
  • 命令行参数启动:chorme --disable-web-security

跨域

JSONP解决跨域
  • 前后台都需要改动
$.ajax({
    url:baseUrl,
    dataType:"jsonp",
    jsonp:"callback",
    success:function(json){
        result=json;
    }
});
  • jsonp发出的请求Type为script请求,返回类型是application/javascript
  • jsonp中的url加了callback参数,后台检测如果有callback参数(参数可约定,一致就行)就是jsonp请求,所以返回类型不是application/json,而是application/javascript。
  • 动态创建js脚本在jquery.js的9800行可以看到
弊端
  • 服务器需要改动代码支持
  • 只支持GET,因为是动态创建script方法来进行请求的,script只能用get方法
  • 发送的不是XHR请求
  • 不建议使用
被调用方解决跨域
服务器端实现
  • 请求是先执行后判断
  • 如果请求是跨域的,会在请求头中加入Origin的url,然后检查响应头中有没有跨域的信息

SpringBoot下的代码

package com.dk.wechat.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * Created by cyj
 * on 2018/7/19.
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}
简单请求与非简单请求

非简单请求发送前会预先发送OPTION方法的预检命令,通过了之后才会发送非简单请求

  1. 简单请求

    • 方法为:GET,POST,HEAD
    • 请求头中无自定义的头
    • Content-Type为
      • text/plain
      • multipart/form-data
      • application/x-www-form-urlencoded
  2. 非简单请求

    • 方法为:put,delete
    • 带自定义头的ajax请求
    • 发送json格式的ajax请求
带Cookie的跨域

Access-Control-Allow-Origin:* 不能满足带cookie的跨域请求,必须指定域名,可以动态配置

Access-Control-Allow-Credentials:true

String origin=request.getHeader("Origin");
if(StringUtil.isEmpty(origin)){
    res.addHeader("Access-Control-Allow-Origin",origin)
}

前端代码:

$.ajax({
    url:baseUrl,
    type:"get",
    xhrFields:{
        withCredentials:true //发送cookie请求
    }
    success:function(json){
        result=json;
    }
});
带自定义头的跨域

同样Access-Control-Allow-Header同样不能是*,可以参考上面的动态配置

前端代码:

$.ajax({
    url:baseUrl,
    type:"get",
    headers:{
        "x-header1":"X"
    }
    beforeSend:function(xhr){
        xhr.setRequestHeader("x-header2","XX")
    }
    success:function(json){
        result=json;
    }
});
Nginx配置
server {
   listen       80; #对外提供的端口
   server_name  localhost;

   location / {
       proxy_pass http://localhost:8080;
       
       add_header Access-Control-Allow-Methods *;
       add_header Access-Control-Max-Age 3600;
       add_header Access-Control-Allow-Credrntials true;
       
       add_header Access-Control-Allow-Origin $http_origin;
       add_header Access-Control-Allow-Headers $http_access_control_request_headers;
   }
   ......
}
Apache服务器配置(Apache24)

httpd-vhosts.conf:

<VirtualHost *:80>
  ServerName localhost
  ErrorLog "logs/localhost-error.log"
  CustomLog "logs/localhost-access.log" common
  ProxyPass / b.com
  
  Header always set add_header Access-Control-Allow-Methods "*";
  Header always set Access-Control-Max-Age "3600";
  Header always set Access-Control-Allow-Credrntials "true";
</VirtualHost>
Spring框架解决
  • 类,方法上加@CrossOrigin
调用方解决跨域
隐藏跨域
  • 反向代理:访问同一个域名下的2个不同URL,会去两个不同的服务器

Nginx配置

server {
    listen       80; #对外提供的端口
    server_name  a.com;

    location / {
        proxy_pass http://localhost:8081;
    }
    
    location /ajax {
        proxy_pass http://localhost:8080;
    }
   ....
}

Apache配置

<VirtualHost *:80>
  ServerName a.com
  ErrorLog "logs/a.com-error.log"
  CustomLog "logs/a.com-access.log" common
  ProxyPass / b.com
  ProxyPass /ajax a.com
  
  Header always set add_header Access-Control-Allow-Methods "*";
  Header always set Access-Control-Max-Age "3600";
  Header always set Access-Control-Allow-Credrntials "true";
</VirtualHost>

参考资料

慕课网上的免费课程,做了笔记,分享一下
ajax跨域完全讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值