1
qgy18 2015-10-19 11:27:52 +08:00 via iPhone 1
你需要弄明白「 Ajax ( XMLHttpRequest )」以及「 JSONP 」的原理,完全不是一回事。 CORS ( Cross Origin Resource Sharing )也可以了解下。
最好自己用原生 JS 分别实现一下, JQ 帮你做了太多事。例如你举的最后那个 case , JQ 帮你把最后的 ? 替换为 callback name ,本质上还是加载并执行一个第三方外链 JS 文件,跟 XHR 没啥关系。 |
2
lydhr OP @qgy18 我使用一下方法是否有问题呢
`$.ajax({ //底层方法; url: myUri, type: "POST", dataType: "json", //使用 JSONP 方法进行 AJAX,json 有跨域问题; success: function (data, status) { $("#hrdMsg").text("success"); }, error: function(obj,info,errObj){ $("#hrdMsg").text("[obj]"+obj+"[info]"+info+"[errObj]"+errObj); } }); ` |
3
lydhr OP @qgy18 我用 chrome 调试可以看到, response header 里面的 content length 和 postman 中的相同,说明成功得到需要的 response ,但是$.ajax 仍然是 fail
|
4
hcymk2 2015-10-19 14:18:17 +08:00
fail 里面应该有 message 吧。还有 chrome 下 response 内容是什么?
|
6
iyaozhen 2015-10-19 15:03:50 +08:00
打快了, jsonp 不支持 post 吧。
|
7
qgy18 2015-10-19 15:29:54 +08:00
@lydhr 本来写了一大段又删掉了。建议楼主还是自己去弄明白原理,这样印象最深刻。
简而言之,你要搞明白 XHR 和 JSONP 的本质区别,你要了解你这个请求真正用的是什么方式去发送的数据(在 Chrome 开发者工具 network Tab 下, XHR 请求会显示在 XHR 下, JSONP 请求会显示在 JS 下)。 不要被 JQ 的 Ajax 给蒙蔽了。 |
9
gamexg 2015-10-19 15:52:34 +08:00 1
浏览器有跨域保护,需要 post 的 api 无法使用(很难)。
这个 api 需要你在你的 asp.net 服务器包装一下这个接口来使用,即: 浏览器 js 调用你的服务器的 api 你服务器 api 收到请求后在调用第三方,然后将第三方的响应返回给浏览器。 |
10
lydhr OP @hcymk2 我用 postman 测试是成功的, postman 的 response 和我的代码的 response 是一摸一样的,但是我的代码 fail 而且没有 message , console 里面报了 access-control-allow-origin 的错;
|
11
lydhr OP @qgy18 我用 postman 测试是成功的, postman 的 response 和我的代码的 request header 除了 origin 其他都是一样的
|
12
matsuijurina 2015-10-19 16:42:06 +08:00
肯定还是跨域的问题,@gamexp 是正解。解决方法在服务器端,比如 golang 就需要加这几句
w.Header().Set("Content-Type", "application/json;charset=UTF-8") w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") Rails 好像改一行代码就可以了。 |
13
qgy18 2015-10-19 16:47:42 +08:00
@lydhr postman 是用 Chrome 扩展发的请求,不受浏览器同源策略限制。
XHR 你如果想要跨域也是可以的,服务端输出 CORS ( Cross Origin Resource Sharing )头就可以了。 |
14
lydhr OP @matsuijurina @gamexg
感觉是跨越问题,服务器是学校的教务处的,只给了 appid 和文档供爱好编程的同学测试用,所以不能修改服务器端。 *** 仍然有两个疑问: - 出于安全学校应该没有 Set("Access-Control-Allow-Origin", "*") ,我在校外可能无法访问,但是为什么 postman 可以,看了一下 postman 的 origin 是: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm - 像微信公众平台等这样的公共接口,是需要大家注册的时候填写自己服务器的 url 的,所以微信接下来做的就是在 Access-Control-Allow-Origin 里面加上我的 url ,我就可以访问了? |
15
lydhr OP @qgy18 postman 的和我的 request 都是 XHR 的,但是 postman 可以 while 我不可以
|
16
hcymk2 2015-10-19 17:52:28 +08:00
|
17
matsuijurina 2015-10-19 18:15:11 +08:00 1
@lydhr 前面很多回复已经讲得很清楚了。不管是你的网页里跑的 JS ,还是 Postman ,它们发的请求远程服务器都收到了,也正常返回了。但是由于浏览器的同源安全策略,在浏览器里运行的 JS 没有权限去访问返回的内容。而 Postman 是一个 Chrome 的 Extension ,虽然它本质上也是用 html 、 css 、 javascript 写出来的,但是 Chrome 给予了它更多的权限,比如 Cross-Origin XMLHttpRequest ,可以解决跨域的问题,具体可参见官方文档 https://developer.chrome.com/extensions/xhr 。
那么,在不能修改远程服务器返回内容的情况下,如何解决你面临的问题呢? @gamexg 已经说了,你需要一个过桥的服务器,比如你用的是 asp.net ,网页上的 JS 不管是 GET 还是 POST 请求都直接发到本地同源的服务器,再由本地服务器向远程服务器提交请求,这时就不再有跨域的问题了。 |
18
qgy18 2015-10-19 19:27:41 +08:00
@lydhr 前面说过了这是浏览器同源策略,扩展在安装的时候就声明过要访问哪些 URL ,你同意了所以没问题。
要想发送跨域 XHR ,除了前面说过的 CORS ,其实你还可以 disable Chrome 的同源策略,因为只作用于你自己的 Chrome ,所以仅供调试,具体做法: Mac : open -a /Applications/Google\ Chrome.app --args --disable-web-security Win : start chrome.exe --args --disable-web-security 上张截图: |
19
codeyung 2015-10-19 19:39:04 +08:00
json != jsonp
|
20
lydhr OP @matsuijurina Best answer. Many thx!
|