什么是跨域访问
在A网站中,我们希望使用Ajax来获得B网站中的特定内容。如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题。你可以理解为两个域名之间不能跨过域名来发送请求或者请求数据,否则就是不安全的。跨域访问违反了同源策略,同源策略规定,浏览器的ajax只能访问跟它的HTML页面同源的资源。
头部关键设置项 头部关键设置项 头部关键设置项(重要事情说三遍)
第一个设置项(重点:能不能访问就是他的原因):Access-Control-Allow-Origin
响应首部中可以携带一个 Access-Control-Allow-Origin
字段,其语法如下:
Access-Control-Allow-Origin: <origin> | *
其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。
例如,下面的字段值将允许来自 http://AABB.com 的跨域请求:
Access-Control-Allow-Origin: http://AABB.com
下面的字段值将允许来自所有地址的跨域请求:
Access-Control-Allow-Origin: *
如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。
第二个设置项(重点:访问的相关设置要客户端、服务器要一致,特别注意Content-Type,提交数据类型JSON、对象、还是数组等等):Access-Control-Expose-Headers
在跨域访问时,XMLHttpRequest对象(AJAX其实就是用这个方法提交数据)的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。
[Access-Control-Expose-Headers
]头让服务器把允许浏览器访问的头放入白名单,例如:
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header
和 X-Another-Custom-Header
响应头了。
第三个设置项(非重点)Access-Control-Max-Age
[Access-Control-Max-Age
]头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。
Access-Control-Max-Age: <delta-seconds>
delta-seconds
参数表示preflight请求的结果在多少秒内有效。
第四个设置项(非重点,服务器配置有问题时看一下) Access-Control-Allow-Credentials
[Access-Control-Allow-Credentials
]头指定了当浏览器的credentials
设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials
。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。
Access-Control-Allow-Credentials: true
第五个设置项(重点:提交数据的方法) Access-Control-Allow-Methods
[Access-Control-Allow-Methods
] 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。
Access-Control-Allow-Methods: <method>[, <method>]*
Access-Control-Allow-Headers
Access-Control-Allow-Headers
首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
解决跨域问题现实中的三种办法
- 跨域变成同域!(将请求页面与被请求地址放在同一域名或者IP地址之下运行)
- 服务器配置跨域(设置项参考前面说到的设置选项)
Apache 服务器
<IfModule mod_headers.c>
<FilesMatch "\.(svg|ttf|otf|eot|woff|woff2)$">
Header set Access-Control-Allow-Origin "*" //设置项 所有地址域名都可以跨域获取本服务器资源
</FilesMatch>
</IfModule>
Nginx
location ~* \.(eot|ttf|woff)$ {
add_header Access-Control-Allow-Origin '*';
}
IIS
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
3.不能改动服务器(改后端项目代码,我这里用PHP说明,其他的可以自己查自己对应后端语言的手册)
<?php
header('content-type:application:json;charset=utf8'); //接收JSON
header('Access-Control-Allow-Origin:*');//所有域名地址
header('Access-Control-Allow-Methods:POST');//post方式提交
header('Access-Control-Allow-Headers:x-requested-with,content-type');
?>
也就是说 后端这样定义以后,前端也要这样提交数据!使用POST 数据 转成JSON,这样后端就能拿到数据,并处理,然后返回 数据给前端同样是 JSON的数据!
也是程序小白,有错的地方大神指点!