>웹 프론트엔드 >JS 튜토리얼 >Ajax 크로스 도메인 문제를 해결하는 방법

Ajax 크로스 도메인 문제를 해결하는 방법

coldplay.xixi
coldplay.xixi원래의
2020-10-29 09:25:272294검색

Ajax 도메인 간 문제에 대한 해결 방법: 1. 액세스를 허용하도록 응답 헤더에 헤더를 추가합니다. 2. jsonp는 요청 가져오기만 지원하고 요청 게시는 지원하지 않습니다. 4. nginx를 사용하여 엔터프라이즈 수준을 구축합니다. 인터페이스 게이트웨이. 추천 무료 학습:

Ajax 크로스 도메인 문제를 해결하는 방법

액세스 허용

Cross-Origin Resource Sharing (CORS) Cross-Origin Resource Sharing 이 크로스 도메인 액세스 솔루션의 보안 기반은 "JavaScript가 이 HTTP 헤더를 제어할 수 없음"을 기반으로 합니다. 대상 도메인에서 반환한 HTTP 헤더를 통한 승인이 필요합니다. 도메인 간 접근을 허용할지 여부입니다.

response.addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问 
response.addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式

해결책 2: jsonp는 get 요청만 지원하고 post 요청은 지원하지 않습니다.

사용법: ①dataType을 jsonp로 변경 ②jsonp: "jsonpCallback"————백엔드로 전송되는 실제 값은 http://입니다. a.a.com/ a/FromServlet?userName=644064&jsonpCallback=jQueryxxx ③백엔드는 get 요청에서 jsonpCallback을 얻습니다. ④콜백 구조를 구성합니다

$.ajax({
type : "GET",
async : false,
url : "http://a.a.com/a/FromServlet?userName=644064",
dataType : "jsonp",//数据类型为jsonp  
jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数
success : function(data) {
alert(data["userName"]);
},
error : function() {
alert('fail');
}
});
 
//后端
        String jsonpCallback = request.getParameter("jsonpCallback");
//构造回调函数格式jsonpCallback(数据)
resp.getWriter().println(jsonpCallback+"("+jsonObject.toJSONString()+")");

JSONP 구현 원칙

동일한 원본 정책에 따라 특정 서버의 페이지는 jsonpCallback을 얻을 수 없습니다. 서버 외부의 데이터, 즉 일반 Ajax는 Cross-Domain 요청을 할 수 없습니다. 그러나 img, iframe 및 script와 같은 태그는 예외입니다. 이러한 태그는 src 속성을 통해 다른 서버에 데이터를 요청할 수 있습니다. 3f1c4e4b6b16bbbd69b2ee476dc4f83a 태그의 공개 정책을 사용하면 도메인 전체에 걸쳐 데이터를 요청할 수 있습니다. 물론 이를 위해서는 서버의 협력이 필요합니다. Jquery에서 ajax의 핵심은 XmlHttpRequest를 통해 이 페이지가 아닌 콘텐츠를 얻는 것이고, jsonp의 핵심은 서버에서 제공하는 js 스크립트를 호출하기 위해 3f1c4e4b6b16bbbd69b2ee476dc4f83a 태그를 동적으로 추가하는 것입니다.

 일반적으로 JSON 데이터를 요청하면 서버는 JSON 형식의 데이터 문자열을 반환하고, JSONP 모드를 사용하여 데이터를 요청하면 서버는 실행 가능한 JavaScript 코드를 반환합니다. jsonp의 도메인 간 원칙은 3f1c4e4b6b16bbbd69b2ee476dc4f83a의 src를 동적으로 로드하는 것이므로 URL을 통해서만 매개변수를 전달할 수 있으므로 jsonp 유형은 get만 가능합니다!

예:

$.ajax({
    url: 'http://192.168.10.46/demo/test.jsp',        //不同的域
    type: 'GET',                                                        // jsonp模式只有GET 是合法的
    data: {
        'action': 'aaron'
    },
    dataType: 'jsonp',                                              // 数据类型
    jsonp: 'jsonpCallback',                                     // 指定回调函数名,与服务器端接收的一致,并回传回来
})

실제로 jquery는 내부적으로

http://192.168.10.46/demo/test.jsp?jsonpCallback=jQuery202003573935762227615_1402643146875&action=aaron으로 변환됩니다. 그런 다음 동적으로

<script type="text/javascript"src="http://192.168.10.46/demo/test.jsp?jsonpCallback= jQuery202003573935762227615_1402643146875&action=aaron"></script>

로드하면 백엔드가 jsonpCallback(Passparameters)을 실행하고 실제 매개변수 형태로 데이터를 전송합니다.

 JSONP 모드를 사용하여 데이터를 요청하는 전체 프로세스: 클라이언트는 요청을 보내고 실행 가능한 함수 이름을 지정합니다(여기서 jQuery는 캡슐화 프로세스를 수행하고 자동으로 콜백 함수를 생성하며 성공 속성 메서드에 대한 데이터를 가져옵니다. 콜백 핸들을 전달하는 대신 호출) 서버는 jsonpCallback 함수 이름을 수락한 다음 실제 매개변수

형식으로 데이터를 보냅니다(jquery 소스 코드에서 jsonp 구현은 < script>를 동적으로 추가하는 것입니다) ; 서버에서 제공하는 js 스크립트를 호출하는 태그입니다. jquery는 3f1c4e4b6b16bbbd69b2ee476dc4f83a 코드가 삽입되면 실행 후 3f1c4e4b6b16bbbd69b2ee476dc4f83a 동시에 비교차 도메인 요청이 최적화되었습니다. 요청이 동일한 도메인 이름에 있는 경우 일반 Ajax 요청처럼 작동합니다.)

해결책 3: httpClient 내부 전달

구현 원칙 매우 간단합니다. 사이트 B에서 Ajax를 통해 결과를 얻기 위해 사이트 A에 액세스하려는 경우 Ajax에 도메인 간 문제가 있지만 사이트 B에서 사이트 B에 액세스하여 결과를 얻으려면 도메인 간 문제가 없습니다. 이 방법은 실제로 B 사이트에서 작동합니다. Ajax는 B 사이트의 HttpClient에 대한 액세스를 요청한 다음 HttpClient를 통해 요청을 전달하여 A 사이트의 데이터 결과를 얻습니다. 그러나 이 방법은 두 개의 요청을 생성하므로 비효율적입니다. 그러나 내부 요청은 패킷 캡처 도구로 분석할 수 없으며 안전합니다.

$.ajax({
type : "GET",
async : false,
url : "http://b.b.com:8080/B/FromAjaxservlet?userName=644064",
dataType : "json",
success : function(data) {
alert(data["userName"]);
},
error : function() {
alert(&#39;fail&#39;);
}
});
 
@WebServlet("/FromAjaxservlet")
public class FromAjaxservlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//创建默认连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建HttpGet对象,处理get请求,转发到A站点
HttpGet httpGet = new HttpGet("http://a.a.com:8080/A/FromServlet?userName="+req.getParameter("userName")); 
                        //执行
CloseableHttpResponse response = httpClient.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
//获取状态
System.out.println("http请求结果为:"+code);
if(code == 200){
                                //获取A站点返回的结果
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
                                //把结果返回给B站点
resp.getWriter().print(result);
}
response.close();
httpClient.close();
} catch (Exception e) {
}
}
}

해결책 4: nginx를 사용하여 엔터프라이즈급 인터페이스 게이트웨이 구축

www.a.a.com은 www.b.b.com의 콘텐츠를 직접 요청할 수 없지만 동일한 도메인 이름을 기반으로 nginx로 구별할 수 있습니다. 프로젝트 이름이 다릅니다. 그것은 무엇을 의미합니까? 다소 추상적일 수도 있습니다. 우리 회사 도메인 이름이 www.nginxtest.com

www.a.a.com에 액세스해야 할 때 www.nginxtest.com/A를 통해 액세스하고 nginx

를 통해 www.a.a.com으로 전달해야 한다고 가정합니다. www.nginxtest.com/B를 통해 www.b.b.com에 접속하고 nginx

를 통해 www.a.a.com으로 전달합니다. 회사의 도메인 이름에 접속하면 "같은 소스"이지만 프로젝트 이름은 다릅니다. 이번에 프로젝트 이름의 역할은 단지 차별화와 편의를 위한 것뿐입니다. 아직도 이해하지 못하신다면 제가 어떻게 구성했는지 살펴보세요:

server {
        listen       80;
        server_name  www.nginxtest.com;
        location /A {
    proxy_pass  http://a.a.com:81;
index  index.html index.htm;
        }
location /B {
    proxy_pass  http://b.b.com:81;
index  index.html index.htm;
        }
    }

我们访问以www.nginxtest.com开头且端口为80的网址,nginx将会进行拦截匹配,若项目名为A,则分发到a.a.com:81。实际上就是通过"同源"的域名,不同的项目名进行区分,通过nginx拦截匹配,转发到对应的网址。整个过程,两次请求,第一次请求nginx服务器,第二次nginx服务器通过拦截匹配分发到对应的网址。

相关免费学习推荐:javascript(视频)

위 내용은 Ajax 크로스 도메인 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.