本文将基于windows,使用Nginx实现跨域访问功能。
注:本文基于前述基础知识,如需要查看,请点这里
协议、域名、子域名、端口至少有一个不一样,则是不同域,否则是同域。示例如下:
(1)http://www.gupao.com 和 https://www.gupao.com 不同域,协议不同
(2)http://www.gupao.com 和 http://www.gupao.net 不同域,域名不同
(3)http://gper.gupao.com 和 http://bbs.gupao.com 不同域,子域名不同
(4)http://www.gupao.com:2673 和 http://www.gupao.com:2674 不同域,端口不同
(5)http://www.gupao.com/index 和 http://www.gupao.com/bbs 同域
当我们在浏览器里访问一个域,不允许它跟另一个域的脚本进行交互。
主要是基于安全考虑,不允许web端同时访问不同的域(服务端)。
原理:使用nginx同时代理 server1和server2,则对于浏览器来说,它只访问了一个地址(nginx服务器的地址),会认为是同一个域,从而实现跨域访问。
(1)nginx.conf配置如下:
server{
listen 8060;
server_name localhost;
当访问/user/csrf 时,去到8062端口
location /user/csrf {
proxy_pass http://localhost:8062;
}
非访问/user/csrf 时,去到8061端口
location / {
proxy_pass http://localhost:8061;
}
}
说明:修改配置后,需要执行 nginx -s reload
(2)csrf.html 示例如下(本示例基于thymeleaf):
this is the csrf file
(3)controller示例如下:
package com.imooc.web.controller;
import com.fasterxml.jackson.annotation.JsonView;
import com.imooc.dto.User;
import com.sun.javafx.UnmodifiableArrayList;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.Request;
import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
/**
* @author linkang
* @time 2022-09-28
* @desc 获取用户信息
* @param id 用户id
*/
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
@JsonView(User.userSimpleView.class)
public User getInfo(@PathVariable String id ){
User user =new User();
user.setUsername(id+"-"+Math.random());
user.setPassword("1234");
System.out.println("##############here:"+id);
return user;
}
/**
* @author linkang
* @time 2022-09-28
* @desc csrf跨域访问示例
*
*/
@RequestMapping("/csrf")
public ModelAndView getCsrf(){
return new ModelAndView("csrf");
}
}
(4)启动模拟服务器并验证
通过修改springboot工程的application.properties的server.port,分别启动8061、8062模拟两台服务器,并分别测试验证下述网址能正常打开:
http://localhost:8061\user\100
http://localhost:8062\user\100
(5)验证nginx配置
使用浏览器打开下述地址,如果正常访问,表示配置正确:
http://localhost:8060/user/csrf
原理:通过使用Nginx代理ajax访问的目标服务器时,在header中添加'Access-Control-Allow-Origin' http://localhost:8062、'Access-Control-Allow-Credentials' true 等信息,使浏览器认为该目标服务器(8061)允许指定服务器(8062)跨域访问,从而放行。
(1)nginx.conf配置如下:
server{
listen 8060;
server_name localhost;
location / {
add_header 'Access-Control-Allow-Origin' http://localhost:8062;
add_header 'Access-Control-Allow-Credentials' true;
add_header 'Access-Control-Allow-Headers' *;
add_header 'Access-Control-Allow-Methods' *;
add_header 'Access-Control-Expose-Headers' *;
proxy_pass http://localhost:8061;
}
}
(2)csrf.html 写法如下:
this is the csrf file
(3)controller示例如下:
package com.imooc.web.controller;
import com.fasterxml.jackson.annotation.JsonView;
import com.imooc.dto.User;
import com.sun.javafx.UnmodifiableArrayList;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.Request;
import javax.jws.soap.SOAPBinding;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
/**
* @author linkang
* @time 2022-09-28
* @desc 获取用户信息
* @param id 用户id
*/
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
@JsonView(User.userSimpleView.class)
public User getInfo(@PathVariable String id ){
User user =new User();
user.setUsername(id+"-"+Math.random());
user.setPassword("1234");
System.out.println("##############here:"+id);
return user;
}
/**
* @author linkang
* @time 2022-09-28
* @desc csrf跨域访问示例
*
*/
@RequestMapping("/csrf")
public ModelAndView getCsrf(){
return new ModelAndView("csrf");
}
}