更新并解决
感谢@Christofer Eliasson的提示。添加:
header("access-control-allow-origin: *");
到我的PHP文件解决了这个问题。也许这不是处理这个问题的最美丽的方式,但这是有效的。
为了让它更好/更安全:
$http_origin = $_SERVER['HTTP_ORIGIN'];
if ($http_origin == "http://domain1.com")
{
header('Access-Control-Allow-Origin: *');
}
这是另一个跨域相关问题。
我在domain1.com上有一个简单的HTML表单,用户可以在其中将他/她的电子邮件添加到邮件列表中,这里有一个位于第二个域(domain2.com(上的简单json文件"mails.json">
当用户提交他/她的电子邮件时,会调用一个JS脚本,其目的是检查电子邮件,并通过ajax GET和JSONP将表单的数据(此处为用户的电子邮件(发送到domain2.com上托管的mails.json文件。
Ajax调用domain2.com上托管的PHP脚本,该脚本应该获取用户的电子邮件并将其写入mails.json。此外,它应该向domain1.com发送一些关于成功或错误的消息,因为用户之前已经输入了他的电子邮件。
目前,电子邮件被发送并保存到mails.json,但我无法让我的PHP脚本将有关其执行的消息发送回domain1。感谢您的建议,请随时检查和修改下面的代码。
HTML表单托管在domain1.com上
<div id="mail">
<form method="post" action="http://domain2.com/script.php" class="notifyme">
<input type="email" value="" name="email" class="email" id="email" placeholder="Type your email here" required>
<input type="submit" value="Get notified »" id="submit" name="submit">
<div class="clear"></div>
</form>
<div class="errmail hide"><span class="uremail"></span> is not a valid email address. Try again :)</div>
<div class="error hide">Ouch :( <span class="uremail"></span> is already registered.</div>
<div class="success hide">Thank You :) <span class="uremail"></span> will be notified once we're ready.</div>
</div>
domain1.com上托管的Javascript文件
//jQuery Initialization
$(function(){
// Form
$('#submit').click(function () { //onSubmit
$('.error,.errmail,.success').hide();
var email = $('input[name=email]').val();
//Email validation
var pattern = new RegExp(/^((([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+(.([a-z]|d|[!#$%&'*+-/=?^_`{|}~]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])+)*)|((x22)((((x20|x09)*(x0dx0a))?(x20|x09)+)?(([x01-x08x0bx0cx0e-x1fx7f]|x21|[x23-x5b]|[x5d-x7e]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(\([x01-x09x0bx0cx0d-x7f]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))))*(((x20|x09)*(x0dx0a))?(x20|x09)+)?(x22)))@((([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|d|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))).)+(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])|(([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])([a-z]|d|-|.|_|~|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF])*([a-z]|[u00A0-uD7FFuF900-uFDCFuFDF0-uFFEF]))).?$/i);
var valid = pattern.test(email);
if (!valid && email !== 'undefined') {
$('.errmail').removeClass('hide').show('fast');
if (!email){$('.uremail').append('This');}
else{$('.uremail').append(email);}
return false;
} else {
//start Ajax
$.ajax({
url: "http://domain2.com/script.php?json_callback=?",
dataType: "jsonp text",
//GET method is used
type: "GET",
//pass the data
data: 'email=' + email,
//Do not cache the page
cache: false,
//Cross Domain
crossDomain: true,
//success
success: function (html) {
//if list.php returned 1/true (send mail success)
if (html==1) {
$('.success').removeClass('hide').show('fast');$('.uremail').append(email);
}
else if (html == 0){
$('.error').removeClass('hide').show('fast');$('.uremail').append(email);
}
else { alert('Sorry, unexpected error. Please try again later.'); }
}
});
}
//cancel the submit button default behaviours
return false;
});
});
更新
托管在domain2.com上的PHP"script.PHP"文件
header('content-type: application/json; charset=utf-8');
$http_origin = $_SERVER['HTTP_ORIGIN'];
if ($http_origin == "http://domain1.com")
{
header('Access-Control-Allow-Origin: *');
}
$logname = 'mails.json';
$logcontents = file_get_contents($logname);
//Retrieve form data.
$email = ($_GET['email']) ?$_GET['email'] : $_POST['email'];
//flag to indicate which method it uses. If POST set it to 1
if ($_POST) $post=1;
if(strpos($logcontents,$email) !== false) {
if ($_POST) {die('You are already subscribed.');}
else{ $result = 0;echo $result; }
}
else {
$filecontents = $email.',';
$fileopen = fopen($logname,'a+');
$filewrite = fwrite($fileopen, json_encode($filecontents) );
$fileclose = fclose($fileopen);
if(!$fileopen or !$filewrite or !$fileclose) {
if ($_POST) {die('Error occured');}
else{ $result = 0;echo $result; }
}
else {
if ($_POST) {echo 'Your email has been added.';}
else{ $result = 1;echo $result; }
}
}
在脚本开头设置正确的内容类型标头时,可以使用常规echo
返回数据。您只需要先准备数据以匹配JSONP格式。类似这样的东西:
<?
// Some data to return
$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
// JSONP response
echo $_GET['callback'] . '('.json_encode($data).')';
?>
// For this example, the response would be something like this:
// jsonp1277656587731([1,2,3,4,5,6,7,8,9])
当您使用jQuery执行JSONP ajax请求时,jQuery将自动发送一个回调GET变量供您在服务器端使用。如示例所示。
一些附加阅读:http://www.geekality.net/2010/06/27/php-how-to-easily-provide-json-and-jsonp/
我过去也遇到过类似的问题,我确实尝试过在Web服务器(Apache2(上修改跨域设置,但没有成功。通过反复尝试,我从ajax调用的"url"参数中删除了主机名,这对我来说很有效。但我仍然没有完全理解。
你能从快速检查url参数吗
http://domain2.com/script.php?json_callback=?
仅:
script.php?json_callback=?.
可能存在其他web服务器配置设置。。但我只是想看看这是否有效。。。。