使用 PHP 和 Javascript/Ajax 绕过 CORS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29837162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bypassing CORS with PHP and Javascript/Ajax
提问by Andre
I've been trying to figure this out for hours, though I'm too uneducated in web development to understand. Heres the case:
我一直在尝试解决这个问题好几个小时,尽管我在 Web 开发方面没有受过教育,无法理解。案例如下:
Another website has a script that they obtain information from the following way:
另一个网站有一个脚本,他们通过以下方式获取信息:
var url = "numbers.php";
parameters = "scoreid=" + document.getElementById('whatscore').value;
parameters += "&num=" + document.getElementById('num1b1').value;
xmlhttp2=GetXmlHttpObject();
if (xmlhttp2==null) {
alert ("Your browser does not support XMLHTTP!");
return;
}
xmlhttp2.onreadystatechange = function() {
if (xmlhttp2.readyState==4) {
scorespot.innerHTML=xmlhttp2.responseText; // load
setScores(document.getElementById('gradelvl').value); // set
document.getElementById('submitscorebtn').style.display="none";
}
}
xmlhttp2.open("POST",url,true);
xmlhttp2.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp2.setRequestHeader("Content-length", parameters.length);
xmlhttp2.setRequestHeader("Connection", "close");
xmlhttp2.send(parameters);
I've attempted to do the same thing, though when I attempt it I get the cross-origin error. I know their are ways to do it with jsonp and other things, though I have no clue where to start at all for this.
我试图做同样的事情,但当我尝试它时,我得到了跨域错误。我知道他们是用 jsonp 和其他东西来做到这一点的,尽管我完全不知道从哪里开始。
When I attempt to directly request information from their page, the numbers.php page, such as example.com/numbers.php?scoreid=131&num=41 . I always get returned with "Error: incorrect parameter syntax".
当我尝试直接从他们的页面请求信息时, numbers.php 页面,例如 example.com/numbers.php?scoreid=131&num=41 。我总是返回“错误:不正确的参数语法”。
Can anybody please tell me how I would fix this in my case? I only know PHP and Javascript well, I'm very uneducated with Ajax and other things or external libraries.
有人可以告诉我如何解决这个问题吗?我只知道 PHP 和 Javascript,我对 Ajax 和其他东西或外部库非常缺乏教育。
I appreciate all help whatsoever! NOTICE: I DO NOT HAVE ACCESS TO THE WEBSERVER.
我感谢所有帮助!注意:我无法访问网络服务器。
回答by
If you do not have access to your server configuration, and if you do not control the external php script (assuming it's not set up to serve as a reverse proxy), then you absolutely cannot use a standalonejavascript solution for this.
如果您无权访问您的服务器配置,并且如果您不控制外部 php 脚本(假设它没有设置为用作反向代理),那么您绝对不能为此使用独立的javascript 解决方案。
Rather, you would have to make the external request from your own local php script. Then you would call your local php script from Ajax, and this willwork since you are accessing a local file, and thus not violating CORS.
相反,您必须从您自己的本地 php 脚本发出外部请求。然后您将从 Ajax 调用您的本地 php 脚本,这将起作用,因为您正在访问本地文件,因此不会违反 CORS。
Here is an example of an Ajax call thru a local PHP script.
Imagine a scenario where you allow users to lookup an album name. The user enters the name of the song, and the artist. You make a request to a 3rd party api, and return the response back to the user via a JavaScript alert notification. For this example, assume the user enters 'Black' and 'Pearl Jam' as the song and artist names
下面是通过本地 PHP 脚本进行 Ajax 调用的示例。
想象一下您允许用户查找专辑名称的场景。用户输入歌曲名称和艺术家。您向第 3 方 api 发出请求,并通过 JavaScript 警报通知将响应返回给用户。对于此示例,假设用户输入“Black”和“Pearl Jam”作为歌曲和艺术家名称
Ajax POST to Local PHP Script with HTML Example:
带有 HTML 示例的 Ajax POST 到本地 PHP 脚本:
<html>
<head>
<!-- Load jQuery Library from Google -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"> </script>
</head>
<body>
<h1> Ajax to local PHP Script Example: </h1>
<form id="getArtist">
Artist: <input type="text" placeholder="Pearl Jam">
Song: <input type="text" placeholder="Black">
<input type="submit" value="Click Here to Active Ajax Call">
</form>
</body>
</html>
<script type='text/javascript'>
$("#getArtist").submit(function(event) { //Listen to when the Submit is pressed
event.preventDefault(); //Stop the submit from actually performing a submit
$.post("local_script.php", { song: "Black", artist: "Pearl Jam", dataType: "json"}) //prepare and execute post
.done(function(response) { //Once we receive response from PHP script
//Do something with the response:
alert("The album name is: " +response);
//Look into JSON.parse and JSON.stringify for accessing data
});
});
</script>
PHP GET
PHP 获取
<?php
$url = 'http://api.music.com/album';
$song = urlencode($_GET['song'])); //Need to url encode
$artist = urlencode($_GET['artist']); //Need to url encode
$response = file_get_contents($url .'?song=' .$song .'&artist=' .$artist);
//**The url looks like http://api.music.com/album?song=Black&artist=Pearl+Jam
//** For purposes of this demo, we will manually assume the JSON response from the API:
$response = '{ "album": "Ten" }'; //(Raw JSON returned by API)
echo $response; //Return the response back to AJAX, assuming it is already returned as JSON. Else encode it json_encode($response)
PHP POST (using curl)
PHP POST(使用 curl)
<?php
$url = 'http://api.music.com/album';
$song = urlencode($_GET['song'])); //Need to url encode
$artist = urlencode($_GET['artist']); //Need to url encode
//$headers = array("Key: " ."Value","Key: " ."Value", //Set any headers, if required.
$post = 'song=' .$song .'&artist=' .$artist; //Prepare Post parameters
/* Configure Curl */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Allow music api to send response
curl_setopt($ch, CURLOPT_POST, 1); //Signifyd that we are doing a POST request
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
//curl_setopt($curl, CURLOPT_HTTPHEADER, $header); //Only if you need to send headers
/* Get Response */
$response = curl_exec($ch);
//** For purposes of this demo, we will manually assume the JSON response from the API:
$response = '{ "album": "Ten" }'; //(Raw JSON returned by API)
echo $response; //Send response back to Ajax, assuming it was already returned in JSON. Else encode it.
Further reading on Ajax requests:
https://api.jquery.com/jquery.get/
https://api.jquery.com/jquery.post/
关于 Ajax 请求的进一步阅读:
https: //api.jquery.com/jquery.get/
https://api.jquery.com/jquery.post/
回答by alexreardon
This may prove useful: How do I send a cross-domain POST request via JavaScript?
这可能很有用:如何通过 JavaScript 发送跨域 POST 请求?
Also, if you do not need to use POST
you could use jsonp
(no CORS setup required)
此外,如果您不需要使用,POST
您可以使用jsonp
(无需 CORS 设置)
回答by Shiji.J
There is NO WAY (using XMLHttpRequest), If you have no control to the remote server
没有办法(使用 XMLHttpRequest),如果您无法控制远程服务器
< comment me the reason for down vote please.
< 请评论我反对票的原因。
CORS introduces a standard mechanism that can be used by all browsers for implementing cross-domain requests. The spec defines a set of headers that allow the browser and server to communicate about which requests are (and are not) allowed
Cross-site HTTP requests initiated from within scripts have been subject to well-known restrictions, for well-understood security reasons. For example HTTP Requests made using the XMLHttpRequest object were subject to the same-origin policy. In particular, this meant that a web application using XMLHttpRequest could only make HTTP requests to the domain it was loaded from, and not to other domains.
CORS 引入了一种标准机制,所有浏览器都可以使用该机制来实现跨域请求。该规范定义了一组标头,允许浏览器和服务器就允许(和不允许)哪些请求进行通信
出于众所周知的安全原因,从脚本内发起的跨站点 HTTP 请求受到众所周知的限制。例如,使用 XMLHttpRequest 对象发出的 HTTP 请求受同源策略的约束。特别是,这意味着使用 XMLHttpRequest 的 Web 应用程序只能向加载它的域发出 HTTP 请求,而不能向其他域发出 HTTP 请求。
That's the rule. Even you may find a way to bypass that, it will be fixed some day, simply because that's a violation of the rule
这就是规则。即使你可能会找到绕过它的方法,它总有一天会被修复,仅仅因为这违反了规则
回答by moberemk
Your easiest solution here is to enable CORS, assuming you control the page you're trying to access, which you can do in a number of different ways as detailed by that site. This error will also go away if you try and make your AJAX request from the same host as the page your Javascript code is running on--same host in this case means from the same domain (including the same subdomain).
此处最简单的解决方案是启用 CORS,假设您控制要访问的页面,您可以通过该站点详述的多种不同方式来执行此操作。如果您尝试从与您的 Javascript 代码运行的页面相同的主机发出 AJAX 请求,此错误也会消失——在这种情况下,相同的主机意味着来自相同的域(包括相同的子域)。