도메인 간 요청 문제를 신속하게 해결: jsonp 및 CORS

인터넷의 각종 크로스 필드 강좌, 각종 실천, 각종 문답은 간단한 jsonp를 제외하고는cors는 모두 통하지 않는다고 많이 말하는데 항상 한두 가지 관건적인 설정이 부족하다.본고는 단지 문제를 해결하고 싶을 뿐, 모든 코드는 직접 실천을 거쳤다.
본고는 크로스 영역에서의 get,post,data,cookie 등 문제를 해결한다.
본고는 get 요청과post 요청만 말할 뿐입니다. 독자는post 요청을 get 요청을 제외한 모든 다른 요청 방식으로 이해해 주십시오.
JSONP
JSONP는 브라우저를 이용하여 스크립트의 자원 인용에 동원 제한이 없고 동적으로 스크립트 탭을 삽입하여 자원이 페이지에 불러오면 바로 실행하는 원리로 크로스 필드를 실현합니다.JSONP는 비공식 전송 프로토콜이다. 이 프로토콜의 요점은 사용자가callback을 전달하거나 처음부터 리셋 방법을 정의할 수 있도록 하는 것이다. 파라미터를 서버에 주고 서버가 데이터를 되돌릴 때 이callback 파라미터를 함수 이름으로 감싸서 클라이언트가 임의로 자신의 함수를 맞춤형으로 만들어서 자동으로 데이터를 처리할 수 있도록 하는 것이다.
JSONP는 GET 요청만 지원하고 POST 등 다른 유형의 HTTP 요청은 지원하지 않습니다. 이것은 크로스 도메인 HTTP 요청만 지원합니다. 서로 다른 도메인의 두 페이지 간에 자바스크립트 호출을 어떻게 하는지를 해결할 수 없습니다. JSONP의 장점은 구식 브라우저를 지원하는 데 있습니다. 폐단도 비교적 뚜렷합니다. 클라이언트와 서비스 측의 맞춤형 개발이 필요합니다. 서비스 측이 되돌아오는 데이터는 표준 Json 데이터가 아니라callback 패키지의 데이터입니다.
jsonp의 원리는 매우 간단하다. [전방에서 정적 자원을 요청할 때 크로스오버 문제가 존재하지 않는다]는 사고방식을 이용했다.
하지만 get만 지원하고 get만 지원하고 get만 지원합니다.
주의해라. 이 방법이 jsonp라고 하는 이상 백엔드 데이터는 반드시 json 데이터를 사용해야 한다. 함부로 문자열을 만들어서는 안 된다. 그렇지 않으면 결과가 영문을 알 수 없다고 느낄 것이다.
프런트엔드 jQuery 쓰기

$.ajax({
type: "get",
url: baseUrl + "/jsonp/get",
dataType: "jsonp",
success: function(response) {
$("#response").val(JSON.stringify(response));
}
});
dataType: “jsonp”.이것을 제외하고 다른 설정은 일반적인 요청과 같다.
백엔드 SpringMVC 구성
만약에 당신도 Spring MVC를 사용한다면 jsonp의 Advice를 설정하면 됩니다. 이렇게 하면 우리가 쓴 모든 컨트롤러 방법은 클라이언트가 jsonp의 요청인지 전혀 고려할 필요가 없습니다. Spring은 자동으로 해당하는 처리를 합니다.

@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
  public JsonpAdvice(){
    //   callback  ,Spring   jsonp  
    super("callback");
  }
}
위의 글은 SpringMVC 버전이 3.2보다 낮지 않고 3.2보다 낮지 않기를 요구합니다. 업그레이드해야 한다고 말할 수 밖에 없습니다.
백엔드 비 SpringMVC 구성
예전에 일을 시작했을 때 Struts2는 하늘을 뒤덮었고 몇 년 동안의 광경은 Spring MVC가 국내 시장을 기본적으로 통치했다.
게으름 피우세요. 여기에 위조 코드를 붙여주세요. 우리의 방법이 앞쪽으로 돌아가기 전에 랩 방법을 조정하세요.

@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
  public JsonpAdvice(){
    //   callback  ,Spring   jsonp  
    super("callback");
  }
}
CORS
Cross-Origin Resource Sharing
CORS는 현대 브라우저가 크로스 자원 요청을 지원하는 방식이다. 전칭'크로스 자원 공유'(Cross-originresourcesharing)라고 한다. XMLHttpRequest를 사용하여 요청을 보낼 때 브라우저가 이 요청이 같은 원본 정책에 부합되지 않는 것을 발견하면 요청 헤더: Origin, 백그라운드에서 일련의 처리를 하고 요청을 받아들이기로 결정하면 결과에 응답 헤더: Access-Control-Allow-Origin을 추가한다.브라우저는 이 상응하는 헤더에 Origin의 값이 포함되어 있는지 판단합니다. 만약에 브라우저가 응답을 처리한다면 우리는 응답 데이터를 얻을 수 있습니다. 만약에 브라우저가 포함되지 않으면 직접 기각할 수 있습니다. 이때 우리는 응답 데이터를 얻을 수 없습니다.
CORS와 JSONP의 사용 목적은 같지만 JSONP보다 더 강력합니다. CORS는 모든 브라우저 요청 유형을 지원하고 불러오는 요청 데이터의 양이 더 크며 개방적이고 간결합니다. 서버는 처리된 데이터를 직접 되돌려주기만 하면 특별한 처리가 필요하지 않습니다.
jsonp는 get 요청만 지원하기 때문에 우리의 모든 요구 사항을 만족시킬 수 없기 때문에cors를 꺼내야 합니다.
국내의 웹 개발자들은 여전히 비교적 핍박을 받는다. 사용자는 브라우저를 업그레이드하지 않고 사장은 개발자에게 호환을 해야 한다.
CORS는 아래의 브라우저를 지원합니다. 현재로서는 브라우저의 문제가 점점 중요하지 않습니다. 타오바오도 IE7을 지원하지 않습니다~~
Chrome 3+
Firefox 3.5+
Opera 12+
Safari 4+
Internet Explorer 8+
프런트엔드 jQuery 쓰기
바로 코드를 보십시오.

$.ajax({
  type: "POST",
  url: baseUrl + "/jsonp/post",
  dataType: 'json',
  crossDomain: true,
  xhrFields: {
    withCredentials: true
  },
  data: {
    name: "name_from_frontend"
  },
  success: function (response) {
    console.log(response)//   json  
    $("#response").val(JSON.stringify(response));
  }
});
dataType: "json", 여기는 json입니다. jsonp가 아닙니다. jsonp가 아닙니다. jsonp가 아닙니다.
crossDomain:true, 크로스 도메인 요청 사용
xhrFields: {withCredentials:true}, 이렇게 설정하면 쿠키를 가져갈 수 있습니다. 그렇지 않으면 세션도 유지할 수 없습니다. 많은 사람들이 여기에 곤두박질칩니다.물론, 만약 당신이 이런 수요가 없다면, 이것을 설정할 필요도 없다.
백엔드 SpringMVC 구성
대부분의 웹 프로젝트에 대해 일반적으로 mvc 관련 설정 클래스가 있는데 이런 종류는 WebMvcConfigurerAdapter에서 계승된다.만약 당신도 Spring MVC 4.2 이상의 버전을 사용한다면 아래와 같이 이 방법을 추가하면 됩니다.

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
 
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**/*").allowedOrigins("*");
  }
}
만약 불행하게도 당신의 프로젝트에서 Spring MVC 버전이 4.2보다 낮다면, 곡선 구국이 필요합니다.

public class CrossDomainFilter extends OncePerRequestFilter {
  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    response.addHeader("Access-Control-Allow-Origin", "*");//   *  , 
    response.addHeader("Access-Control-Allow-Credentials", "true");
    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    response.addHeader("Access-Control-Allow-Headers", "Content-Type");
    filterChain.doFilter(request, response);
  }
}
웹에서xml에서 filter 설정:

<filter>
  <filter-name>CrossDomainFilter</filter-name>
  <filter-class>com.javadoop.filters.CrossDomainFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CrossDomainFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
shiro를 사용하는 항목도 많고, shiro 필터를 설정하는 방식도 있는데, 여기서는 소개하지 않겠습니다.
주의해라, 내가 말한 것은 매우 두루뭉술한 배치인데, 대부분의 항목에 대해 이렇게 두루뭉술하게 배치할 수 있다.문장에서 "*"와 같은 설정은 독자들이 어떻게 어울리는지 알 수 있을 것이다.
만약 독자가 브라우저 알림이'*'기호를 사용할 수 없다는 것을 발견한다면, 독자는 위의 filter에서 리퀘스트 대상에 따라 요청 헤더에 있는 리퀘스트(request.getHeader('referer')를 받은 다음'Access-Control-Allow-Origin'을 동적으로 설정할 수 있습니다.

String referer = request.getHeader("referer");
if (StringUtils.isNotBlank(referer)) {
  URL url = new URL(referer);
  String origin = url.getProtocol() + "://" + url.getHost();
  response.addHeader("Access-Control-Allow-Origin", origin);
} else {
  response.addHeader("Access-Control-Allow-Origin", "*");
}
프런트엔드 비jQuery 쓰기
jQuery를 한 방에 다 먹을 수 있는 날은 아예 없습니다. jQuery를 사용하지 않으면post 크로스오버를 어떻게 해결할 수 있는지 말씀해 주세요.
네이티브 js를 소개합니다.

function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    //   withCredentials  ,  XMLHTTPRequest2  。 
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    //   IE  
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    //  , ,  CORS
    xhr = null;
  }
  return xhr;
}
 
var xhr = createCORSRequest('GET', url);
if (!xhr) {
  throw new Error('CORS not supported');
}
그 중에서 Chrome, Firefox, Opera, Safari 등'프로그래머 친선'브로저는 XMLHTTPRequest2 대상을 사용합니다.IE는 XDomainRequest를 사용합니다.
총결산
이상은 본고가 크로스오버 요청 문제를 신속하게 해결하는 데 관한 것입니다. jsonp와cors의 모든 내용이 여러분에게 도움이 되기를 바랍니다.관심 있는 친구는 본 사이트의 다른 관련 주제를 계속 참고할 수 있습니다. 부족한 점이 있으면 댓글로 지적해 주십시오!

좋은 웹페이지 즐겨찾기