jQuery $ .ajax (), Firefox에서 REQUEST_METHOD로“OPTIONS”를 보내는 $ .post
비교적 간단한 jQuery 플러그인이라고 생각했던 것에 문제가 있습니다 ...
플러그인은 ajax를 통해 PHP 스크립트에서 데이터를 가져 와서에 옵션을 추가해야합니다 <select>
. 아약스 요청은 매우 일반적입니다.
$.ajax({
url: o.url,
type: 'post',
contentType: "application/x-www-form-urlencoded",
data: '{"method":"getStates", "program":"EXPLORE"}',
success: function (data, status) {
console.log("Success!!");
console.log(data);
console.log(status);
},
error: function (xhr, desc, err) {
console.log(xhr);
console.log("Desc: " + desc + "\nErr:" + err);
}
});
이것은 Safari에서 잘 작동하는 것 같습니다. Firefox 3.5 REQUEST_TYPE
에서 서버는 항상 'OPTIONS'이며 $ _POST 데이터는 나타나지 않습니다. Apache는 요청을 'OPTIONS'유형으로 기록합니다.
::1 - - [08/Jul/2009:11:43:27 -0500] "OPTIONS sitecodes.php HTTP/1.1" 200 46
이 ajax 호출이 Safari에서는 작동하지만 Firefox에서는 작동하지 않는 이유는 무엇이며 Firefox에서는 어떻게 해결할 수 있습니까?
응답 헤더 날짜 : 2009 년 7 월 8 일 수요일 21:22:17 GMT 서버 : Apache / 2.0.59 (Unix) PHP / 5.2.6 DAV / 2 X-Powered-By : PHP / 5.2.6 내용 길이 46 연결 유지 시간 종료 = 15, 최대 = 100 연결 유지 컨텐츠 유형 텍스트 / html 요청 헤더 호스트 주문 양식 : 8888 User-Agent Mozilla / 5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv : 1.9.1) Gecko / 20090624 Firefox / 3.5 text / html, application / xhtml + xml, application / xml; q = 0.9, * / *; q = 0.8 수락 수락 언어 en-us, en; q = 0.5 수락 인코딩 gzip, 수축 수락 문자셋 ISO-8859-1, utf-8; q = 0.7, *; q = 0.7 Keep-Alive 300 연결 유지 오리진 http://ux.inetu.act.org 액세스 제어 요청 방법 POST 액세스 제어 요청 헤더 x- 요청
다음은 Firebug 출력 사진입니다.
오류의 원인은 동일한 오리진 정책입니다. XMLHTTPRequests는 자신의 도메인에만 수행 할 수 있습니다. JSONP 콜백을 대신 사용할 수 있는지 확인하십시오 .
$.getJSON( 'http://<url>/api.php?callback=?', function ( data ) { alert ( data ); } );
Django 측에서 다음 코드를 사용하여 OPTIONS 요청을 해석하고 필요한 Access-Control 헤더를 설정했습니다. 그 후 Firefox의 교차 도메인 요청이 작동하기 시작했습니다. 앞에서 말했듯이 브라우저는 먼저 OPTIONS 요청을 보낸 다음 POST / GET 직후에
def send_data(request):
if request.method == "OPTIONS":
response = HttpResponse()
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
response['Access-Control-Max-Age'] = 1000
# note that '*' is not valid for Access-Control-Allow-Headers
response['Access-Control-Allow-Headers'] = 'origin, x-csrftoken, content-type, accept'
return response
if request.method == "POST":
# ...
편집 : 적어도 경우에 따라 실제 응답에 동일한 Access-Control 헤더를 추가 해야하는 것으로 보입니다. 요청이 성공한 것처럼 보이기 때문에 약간 혼란 스러울 수 있지만 Firefox는 응답 내용을 Javascript로 전달하지 않습니다.
이 mozilla 개발자 센터 기사 는 다양한 도메인 간 요청 시나리오를 설명합니다. 이 기사에서는 컨텐츠 유형이 'application / x-www-form-urlencoded'인 POST 요청을 '단순 요청'( '프리 플라이트'OPTIONS 요청없이)으로 보내야한다고 지적합니다. 그러나 POST가 해당 컨텐츠 유형으로 전송되었지만 Firefox가 OPTIONS 요청을 보냈습니다.
'Access-Control-Allow-Origin'응답 헤더를 '*'로 설정 한 서버에서 옵션 요청 핸들러를 작성하여이 작업을 수행 할 수있었습니다. ' http://someurl.com ' 과 같이 특정 항목으로 설정하면 더 제한적일 수 있습니다 . 또한 여러 출처의 쉼표로 구분 된 목록을 지정할 수 있지만이 작업을 수행 할 수는 없다는 것을 읽었습니다.
Firefox가 허용 가능한 'Access-Control-Allow-Origin'값으로 OPTIONS 요청에 대한 응답을 받으면 POST 요청을 보냅니다.
완전히 아파치 기반 솔루션을 사용하여이 문제를 해결했습니다. 내 vhost / htaccess에서 다음 블록을 넣습니다.
# enable cross domain access control
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
# force apache to return 200 without executing my scripts
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
Apache가 대상 스크립트를 실행할 때 발생하는 상황에 따라 후자가 필요하지 않을 수 있습니다. 신용은 후자에 대해 친숙한 ServerFault 사람들 에게 전달됩니다.
응답 스크립트 상단의 PHP가 작동하는 것 같습니다. (Firefox 3.6.11에서는 아직 많은 테스트를 수행하지 않았습니다.)
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
if(array_key_exists('HTTP_ACCESS_CONTROL_REQUEST_HEADERS', $_SERVER)) {
header('Access-Control-Allow-Headers: '
. $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
} else {
header('Access-Control-Allow-Headers: *');
}
if("OPTIONS" == $_SERVER['REQUEST_METHOD']) {
exit(0);
}
Google지도에 요청을 보내는 것과 동일한 문제가 있었고 jQuery 1.5를 사용하면 솔루션이 매우 간단합니다. dataType: "jsonp"
Culprit는 OPTIONS 방법을 사용한 프리 플라이트 요청입니다
사용자 데이터에 부작용을 일으킬 수있는 HTTP 요청 방법 (특히 GET 이외의 HTTP 방법 또는 특정 MIME 유형의 POST 사용)의 경우, 사양은 브라우저가 요청을 "사전 비행"하도록 요구하여 서버에서 HTTP OPTIONS 요청 메소드를 사용한 후 서버에서 "승인"하면 실제 HTTP 요청 메소드로 실제 요청을 보냅니다.
웹 사양은 https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS를 참조하십시오.
Nginx conf에 다음 줄을 추가하여 문제를 해결했습니다.
location / {
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "POST, GET, PUT, UPDATE, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization";
add_header Access-Control-Allow-Credentials "true";
add_header Content-Length 0;
add_header Content-Type text/plain;
return 200;
}
location ~ ^/(xxxx)$ {
if ($request_method = OPTIONS) {
rewrite ^(.*)$ / last;
}
}
JSONP를 사용할 때 소스 1.3.2를 살펴보면 브라우저 동일한 도메인 정책을 통과하는 SCRIPT 요소를 동적으로 작성하여 요청합니다. 당연히 SCRIPT 요소를 사용하여 POST 요청을 할 수 없으며 브라우저는 GET을 사용하여 결과를 가져옵니다.
JSONP 호출을 요청하면 SCRIPT 요소는 AJAX 호출 유형이 GET으로 설정된 경우에만 수행되므로 SCRIPT 요소가 생성되지 않습니다.
http://dev.jquery.com/ticket/4690
ASP.Net에서 이와 같은 문제가 발생했습니다. $.post
PageHandlerFactory로 인해 일부 HTML 콘텐츠를 가져 오기 위해 jQuery 를 실행하려고 할 때 IIS가 내부 서버 오류를 반환했습니다 GET,HEAD,POST,DEBUG
. 따라서 "OPTIONS"동사를 목록에 추가하거나 "All Verbs"를 선택하여 해당 제한을 변경할 수 있습니다.
IIS 관리자에서 웹 사이트를 선택한 다음 처리기 매핑을 선택하고 필요에 따라 * .apx 파일의 PageHandlerFactory를 두 번 클릭하십시오 (프레임 워크 4.0과 함께 통합 응용 프로그램 풀을 사용함). 요청 제한을 클릭 한 다음 동사 탭으로 이동하여 수정 사항을 적용하십시오.
이제 우리의 $.post
요청이 예상대로 작동합니다 :)
양식의 action
URL www
에 도메인 의 일부가 포함되어 있는지 확인하고 , 열려있는 원본 페이지는없이 표시 www
됩니다.
일반적으로 정식 Urls ..
나는이 기사를 다루기 전에 몇 시간 동안 고생했으며 크로스 도메인의 힌트를 발견했습니다.
o.url = 'index.php'
이 파일이 존재하면 콘솔에 성공 메시지가 표시되는 것 같습니다 . url을 사용하면 오류가 반환됩니다.http://www.google.com
게시 요청을하는 경우 $ .post 메소드 를 직접 사용하지 않는 이유는 무엇입니까?
$.post("test.php", { func: "getNameAndTime" },
function(data){
alert(data.name); // John
console.log(data.time); // 2pm
}, "json");
너무 간단합니다.
POST하려는 도메인의 서버 코드를 제어하는 경우이를 해결하는 방법에 대한 명확한 예를 게시했습니다. 이 답변은이 글에서 다루었지만 IMO를보다 명확하게 설명합니다.
JavaScript를 통해 도메인 간 POST 요청을 보내려면 어떻게합니까?
이에 대한 해결책은 다음과 같습니다.
- dataType을 사용하십시오.
json
&callback=?
귀하의 URL에 추가
이것은 Facebook API와 Firefox를 호출하는 데 효과적이었습니다. 위의 조건 (둘 다) GET
대신 Firebug가 사용 중 OPTIONS
입니다.
문제를 피할 수있는 또 다른 가능성은 프록시 스크립트를 사용하는 것입니다. 그 방법은 예 를 들어 여기에 설명되어 있습니다
당신이없이 이것을 시도 할 수 있습니다
contentType:application/x-www-form-urlencoded
옵션을 추가하십시오 :
dataType : "json"
function test_success(page,name,id,divname,str)
{
var dropdownIndex = document.getElementById(name).selectedIndex;
var dropdownValue = document.getElementById(name)[dropdownIndex].value;
var params='&'+id+'='+dropdownValue+'&'+str;
//makerequest_sp(url, params, divid1);
$.ajax({
url: page,
type: "post",
data: params,
// callback handler that will be called on success
success: function(response, textStatus, jqXHR){
// log a message to the console
document.getElementById(divname).innerHTML = response;
var retname = 'n_district';
var dropdownIndex = document.getElementById(retname).selectedIndex;
var dropdownValue = document.getElementById(retname)[dropdownIndex].value;
if(dropdownValue >0)
{
//alert(dropdownValue);
document.getElementById('inputname').value = dropdownValue;
}
else
{
document.getElementById('inputname').value = "00";
}
return;
url2=page2;
var params2 = parrams2+'&';
makerequest_sp(url2, params2, divid2);
}
});
}
Facebook API를 사용하는 데 비슷한 문제가있었습니다.
프리 플라이트 요청을 보내지 않은 유일한 contentType은 text / plain 인 것 같았습니다. 여기서 mozilla에 언급 된 나머지 매개 변수는 아닙니다.
- 왜 이것이 유일한 브라우저입니까?
- Facebook에서 프리 플라이트 요청을 알고 수락하지 않는 이유는 무엇입니까?
참고 : 앞에서 언급 한 Moz 문서는 X-Lori 헤더가 프리 플라이트 요청을 트리거해야한다고 제안하지만 그렇지 않습니다.
서버 측에서 일부 작업을 수행해야합니다. 서버 측에서 PHP를 사용하고 있지만 .NET 웹 응용 프로그램 솔루션은 다음과 같습니다 .jQuery.ajax에서 content-type을 'application / json'으로 설정할 수 없습니다
PHP 스크립트에서도 똑같이하면 작동합니다. 간단히 : 처음에는 브라우저가 서버에 요청하여 해당 유형의 데이터를 전송할 수 있는지 여부를 확인하고 두 번째 요청은 적절하거나 허용됩니다.
다음을 추가하십시오.
dataType: "json",
ContentType: "application/json",
data: JSON.stringify({"method":"getStates", "program":"EXPLORE"}),
다른 서버에서 호스팅되는 Apache Solr에 데이터를 게시하려고 할 때 프록시 URL을 사용하여 비슷한 문제를 해결했습니다. (완벽한 답변은 아니지만 내 문제를 해결합니다.)
이 URL을 따르십시오 : Proxying을 위해 Mode-Rewrite를 사용하여 httpd.conf에 다음 행을 추가하십시오.
RewriteRule ^solr/(.*)$ http://ip:8983/solr$1 [P]
따라서 http : // ip : 8983 / solr / *에 데이터를 게시하는 대신 / solr에 데이터를 게시 할 수 있습니다 . 그런 다음 동일한 출처에 데이터를 게시합니다.
PHP에서 내 cors 상황을 잘 처리하는이 코드가 이미 있습니다.
header( 'Access-Control-Allow-Origin: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Headers: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Credentials: true' );
그리고 로컬 및 원격에서 잘 작동했지만 원격에서는 업로드하지 않았습니다.
apache / php 또는 내 코드에서 어떤 일이 발생합니다 .OPTIONS를 요청할 때 cors 규칙으로 헤더를 반환하지만 302 결과로 검색하지 않아도됩니다. 따라서 브라우저가 허용 가능한 상황으로 인식되지 않습니다.
@Mark McDonald 답변을 기반으로 한 것은 헤더 뒤에이 코드를 넣는 것입니다.
if( $_SERVER['REQUEST_METHOD'] === 'OPTIONS' )
{
header("HTTP/1.1 202 Accepted");
exit;
}
이제 요청 OPTIONS
하면 헤더와 202 결과를 보냅니다.
명심하시기 바랍니다:
JSONP는 GET 요청 방법 만 지원합니다.
* firefox로 요청 보내기 : *
$.ajax({
type: 'POST',//<<===
contentType: 'application/json',
url: url,
dataType: "json"//<<=============
...
});
위의 요청은 OPTIONS (==> 유형 : 'POST' )로 보내십시오 !!!!
$.ajax({
type: 'POST',//<<===
contentType: 'application/json',
url: url,
dataType: "jsonp"//<<==============
...
});
그러나 위의 요청은 GET으로 전송합니다 (==> 유형 : 'POST' ) !!!!
"도메인 간 통신"상태 인 경우주의를 기울이고주의하십시오.
'Programing' 카테고리의 다른 글
SQL에서 "0으로 나누기"오류를 피하는 방법은 무엇입니까? (0) | 2020.03.05 |
---|---|
공백의 끝 및 / 또는 시작 부분에 공백을 유지하는 방법은 무엇입니까? (0) | 2020.03.05 |
Chrome에서 '일반 재로드', '하드 재로드'및 '빈 캐시 및 하드 재로드'의 차이점은 무엇입니까? (0) | 2020.03.05 |
퍼블릭 필드와 자동 속성 (0) | 2020.03.05 |
python unittest-assertRaises의 반대? (0) | 2020.03.05 |