天气,地图API/跨域/代理转发

937 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情。这是参与fullstackopen 2022课程Data for Countries练习遇到的问题。

实现功能

Api restcountries.com 以机器可读的格式,提供了不同国家的大量数据。创建一个应用,可以查看不同国家的数据。 应用能从all中获取数据。用户界面非常简单。 通过在搜索字段中键入搜索查询,可以找到要显示的国家。

1.在显示单个国家数据的视图中添加该国首都的天气报告。 有几十个天气数据提供商。 推荐的一个API 是 openweathermap.org

2.当少于10个国家,但多于1个,则显示所有匹配查询的国家,在国家名称旁边有一个按钮,当按下该按钮时,显示该国的视图:

image.png

API提供给本例的JSON数据形式

  1. 天气,给了首都的经纬度 image.png

  2. 地图,给了地图的链接 maps.png

用axios.get请求数据时遇到问题

1.从OpenWeatherMap获取天气

axios.get(url,(req,res)=>{ })请求提供的网址,报错:

image.png

这波纯属没搞清get请求url的原理,操作失误了,直接用了提供的网站地址。进官网后可以看到其实是提供了天气查询的API接口的,需要注册,生成一个api-key,然后根据文档使用,很简单。

进入官网,注册账号: image.png 生成api-key: image.png

注意:不要将 api-key 保存到源代码管理Git中,也不能将 api-key 硬编码到源代码中。使用环境变量来保存密钥。 将密钥保存到.env文件:

# .env
REACT_APP_API_KEY='b2a8f5dc976ea04b6153bbf7b9bfe1b8' 

然后从 process.env 对象访问密钥的值:

const api_key = process.env.REACT_APP_API_KEY
// variable api_key has now the value set in startup

调用形式官网都可以看到openweathermap.org/current

用iframe框架嵌入网站时遇到的问题

  1. 本来想用API返回给我们的url,直接<iframe src="https://goo.gl/maps/tiQ9Baekb1jQtDSD9"></iframe>标签嵌套一个谷歌地图,结果浏览器报错: image.png image.png 原因:不是所有网站,直接复制网址出去就给iframe/object嵌套的,浏览器会依据X-Frame-Options的值来控制iframe/object框架的页面是否允许加载显示,这里sameorigin ,表示只能被同源的iframe 引用,跨域名的iframe 没法显示了。所以解决这个问题一般是在server端,设置http请求头。网站可以使用此功能,来确保自己网站的内容没有被嵌套到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。

点击劫持技术可以用嵌入代码或者文本的形式出现,在用户毫不知情的情况下完成攻击,比如点击一个表面显示是“播放”某个视频的按钮,而实际上完成的操作却是将用户的社交网站个人信息改为“公开”状态。

非要用iframe嵌套这个这个地图到我自己网站呢?要看这个网站本身有没有提供一个可以<iframe>嵌入页面的代码。包括想嵌入一些视频网站的视频,音乐,都可以直接上网站然后找网站自己提供给我们的适用的iframe代码。点进API返回的网址,可以显示地图,发现有提供:

image.png

但我们从数据库只能获取到该url,并不能得到适用于嵌套的代码(除非写爬虫)。纯前端不能解决,最终找到一种思路:

将不能跨域访问的url的host设置为你网站的域名,这一步是为了即使浏览器对url发起请求,因为host是你服务器的域名,请求也会进入到你的服务器;第二步用中间件,去掉响应头里的x-frame-options限制。这样就类似于模拟了从浏览器空页面直接访问的效果,规避了同源限制。

源的继承:在页面中通过 about:blank 或 javascript: URL 执行的脚本会继承打开该 URL 的文档的源,因为这些类型的 URLs 没有包含源服务器的相关信息。

目前代码上还没有解决,之后解决了再来更新吧目前代码上还没有解决,之后解决了再来更新吧或许题目要求我实现点击按钮跳转呢,直接设置button的onClick,window.open(event.target.value)解决,所以要考虑需求和后端给的数据合不合理呢!!!

同源策略和跨域资源共享

如果两个 URL(Universal Resource Locator 统一资源定位符,俗称网页地址)的 协议protocol/主机host/端口port(如果有指定的话) 都相同的话,则这两个 URL 是同源。同源策略是一个重要的安全策略,它用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。违背同源策略就是跨域。

image.png

网上有很多解决跨域方案

CORS  

是一种基于HTTP头的机制,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

代理转发

同源策略是浏览器设置的安全策略,我们只要不通过浏览器直接发送请求,而是通过服务器来发送请求,服务器和服务器之间可以互相请求数据,没有跨域概念,我们配置一个代理的服务器代替客户端去请求目的服务器中的数据,然后代理服务器把请求到的数据再返回到客户端。

浏览器请求响应模型

最后再温习一下:

Snipaste_2022-04-22_09-48-01.png