新手,已知某 web 服务的文档和 appid,应该如何调用 api

2015-10-19 10:27:46 +08:00
 lydhr
3151 次点击
所在节点    jQuery
20 条回复
qgy18
2015-10-19 11:27:52 +08:00
你需要弄明白「 Ajax ( XMLHttpRequest )」以及「 JSONP 」的原理,完全不是一回事。 CORS ( Cross Origin Resource Sharing )也可以了解下。

最好自己用原生 JS 分别实现一下, JQ 帮你做了太多事。例如你举的最后那个 case , JQ 帮你把最后的 ? 替换为 callback name ,本质上还是加载并执行一个第三方外链 JS 文件,跟 XHR 没啥关系。
lydhr
2015-10-19 13:31:12 +08:00
@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);
}
}); `
lydhr
2015-10-19 13:54:15 +08:00
@qgy18 我用 chrome 调试可以看到, response header 里面的 content length 和 postman 中的相同,说明成功得到需要的 response ,但是$.ajax 仍然是 fail
hcymk2
2015-10-19 14:18:17 +08:00
fail 里面应该有 message 吧。还有 chrome 下 response 内容是什么?
iyaozhen
2015-10-19 14:52:26 +08:00
@lydhr 你这里有错误。
iyaozhen
2015-10-19 15:03:50 +08:00
打快了, jsonp 不支持 post 吧。
qgy18
2015-10-19 15:29:54 +08:00
@lydhr 本来写了一大段又删掉了。建议楼主还是自己去弄明白原理,这样印象最深刻。

简而言之,你要搞明白 XHR 和 JSONP 的本质区别,你要了解你这个请求真正用的是什么方式去发送的数据(在 Chrome 开发者工具 network Tab 下, XHR 请求会显示在 XHR 下, JSONP 请求会显示在 JS 下)。

不要被 JQ 的 Ajax 给蒙蔽了。
lydhr
2015-10-19 15:51:34 +08:00
@iyaozhen 注释与实际代码不符, datatype 是用的 json
gamexg
2015-10-19 15:52:34 +08:00
浏览器有跨域保护,需要 post 的 api 无法使用(很难)。
这个 api 需要你在你的 asp.net 服务器包装一下这个接口来使用,即:
浏览器 js 调用你的服务器的 api
你服务器 api 收到请求后在调用第三方,然后将第三方的响应返回给浏览器。
lydhr
2015-10-19 15:55:12 +08:00
@hcymk2 我用 postman 测试是成功的, postman 的 response 和我的代码的 response 是一摸一样的,但是我的代码 fail 而且没有 message , console 里面报了 access-control-allow-origin 的错;
lydhr
2015-10-19 16:04:30 +08:00
@qgy18 我用 postman 测试是成功的, postman 的 response 和我的代码的 request header 除了 origin 其他都是一样的
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 好像改一行代码就可以了。
qgy18
2015-10-19 16:47:42 +08:00
@lydhr postman 是用 Chrome 扩展发的请求,不受浏览器同源策略限制。

XHR 你如果想要跨域也是可以的,服务端输出 CORS ( Cross Origin Resource Sharing )头就可以了。
lydhr
2015-10-19 17:43:47 +08:00
@matsuijurina @gamexg
感觉是跨越问题,服务器是学校的教务处的,只给了 appid 和文档供爱好编程的同学测试用,所以不能修改服务器端。
***
仍然有两个疑问:
- 出于安全学校应该没有 Set("Access-Control-Allow-Origin", "*") ,我在校外可能无法访问,但是为什么 postman 可以,看了一下 postman 的 origin 是: chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm
- 像微信公众平台等这样的公共接口,是需要大家注册的时候填写自己服务器的 url 的,所以微信接下来做的就是在 Access-Control-Allow-Origin 里面加上我的 url ,我就可以访问了?
lydhr
2015-10-19 17:46:13 +08:00
@qgy18 postman 的和我的 request 都是 XHR 的,但是 postman 可以 while 我不可以
hcymk2
2015-10-19 17:52:28 +08:00
matsuijurina
2015-10-19 18:15:11 +08:00
@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 请求都直接发到本地同源的服务器,再由本地服务器向远程服务器提交请求,这时就不再有跨域的问题了。
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

上张截图:

codeyung
2015-10-19 19:39:04 +08:00
json != jsonp
lydhr
2015-10-22 13:20:28 +08:00
@matsuijurina Best answer. Many thx!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/229115

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX