文章目录
今天要介绍的是clone下来的vue项目出现“An unknown git error occurred”的问题和vue全局挂载axios及配置全局请求和响应拦截,uni-app的全局请求和响应拦截的实现和对请求方法的封装。
我们经常从GitHub上下载项目的话可能对这类错误见的比较多。首先,这是一个SSH的错误,我们需要把ssh改为https,可以输入以下指令:
git config --global http.proxy http://127.0.0.1:1080 git config --global https.proxy https://127.0.0.1:1080
然后再重新下载npm即可。
我们在vue2中全局挂载axios的方法一般是这样:
在入口文件main.js中:
//先导入axios:
import Axios from 'axios';
//然后使用prototype将axios添加为vue实例的原型属性;
Vue.prototype.$http = Axios;
这样就可以在其他的组件里面不经过导入就可以直接通过this.$http使用axios;

要认识到vue3与vue2的区别,vue3取消了Vue.prototype,并且提供了新的用于全局挂载属性或对象的API:globalProperties:
import axios from 'axios';
app.config.globalProperties.$http = axios;
和上面类似,要调用axios就不用再次导入,但是可以直接使用$http吗?不能! 在vue3中一个属性或者对象若是想要在所有的组件实例内被访问到的话,注册挂载到全局的property 的对象只是第一步,要想调用全局的对象或者属性需要通过getCurrentInstance获得当前的实例,再由当前的实例找到全局实例对象appContext,进而获取全局实例config.globalProperties;
在组件中写法如下:
const currentInstance = getCurrentInstance();
const { $http } = currentInstance.appContext.config.globalProperties;
此时在组件内就可以使用$http调用axios了;
实际上,globalProperties是对Vue2中的prototype的一种替换,与任何全局的东西一样,必须谨慎使用,需要注意的是,若是全局属性与组件自己的属性发生冲突的话,组件自身的属性是优先的。
我们可以在项目中指定的目录下创建一个专门用于配置拦截器的文件,我们可以在这里对axios进行统一的封装。
// 先导入axios:
import axios from "axios";
// 请求路径:
const ipAddress1 = 'http://192.168.1.105:8080/api/v1';
const ipAddress2 = 'http://192.168.1.117:8080/api/v1'
// 自带上token的方法:
const addToken = (config: any) => {
// 检测缓存中是否带有token:
if (sessionStorage.getItem('token')) {
// 若是配置中带有请求头的话直接加上token
if (config.headers) {
return config.headers.authorization = sessionStorage.getItem('token');
}
// 配置信息中若是没有请求头的话也可以让其加上请求头,再带上token:
config.headers = {
authorization: sessionStorage.getItem('token')
}
}
}
// 创建一个axios的对象:
const instance = axios.create({
baseURL: `${ipAddress1}`,
timeout: 3000,
headers: {
}
})
// 配置全局请求拦截:
// 请求拦截器:可以根据需要修改配置
instance.interceptors.request.use((config: any) => {
addToken(config);//带上token;
return config;
}, (err: any) => {
return Promise.reject(err);
})
// 响应拦截器:可以根据需要修改配置
instance.interceptors.request.use((res: any) => {
return res;
}, (err: any) => {
return Promise.reject(err);
})
// 导出请求对象:
export default instance;
一般的请求拦截就是这样配置。那么我们将其导入入口文件main.js/ts即可:
import "../src/http/interceptor";
然后在项目的任何地方发送网络请求,拦截器都会生效;
在uni-app中要配置拦截器其实也差不了太多,也是在指定的目录下创建一个配置文件,基本内容一般为:
// 带上默认路径:
const BASE_URL:String="https://jsonplaceholder.typicode.com"
// 带上token的方法;
function addToken(args:any){
if(uni.getStorageSync("token")){
if(args.header){
return args.header.authorization=uni.getStorageSync("token");
}
args.header={
authorization:uni.getStorageSync("token")
}
}
}
// 用于配置全局请求拦截器
uni.addInterceptor("request",{
invoke(args){
// 配置默认请求方式:
if(args.method===undefined) return args.method="POST";
// 获取token
args.url=BASE_URL+args.url
addToken(args)
console.log('拦截器生效')
},
success({
data:res
}){
if(res.status===511){
uni.reLaunch({
url: '/pages/login_register/login'
})
}
}
})
然后在全局的入口文件main.js/ts中导入:
// 导入全局拦截:
import "@/http/interceptor"
发送网络请求的时候即可生效。
值得一提的是上面请求拦截器中有个invoke回调函数,表示拦截前触发,可以在其中先做一些基本的配置,比如添加请求路径,获取token等等。
一般我们进行网络请求的时候使用的都是异步处理方法,因为同步等待网络请求的响应可能会导致后续的数据、页面卡顿或者无法加载且执行效率低下。一般我们可以使用promise或者async await的方法进行封装调用。
vue项目:
我们以http目录作为请求拦截、请求方法封装的目录:
我们在request_methods.ts中封装好请求的方法:
使用promise,方便再调用导出的时候使用async await一起使用,效果更佳。
// 封装各种请求的方法:
import http from '../http/interceptor';
import qs from 'qs';
// 为参数对象option编写接口:
interface option {
// option的基本选项:请求路径,请求参数,成功回调和失败回调;
url: any,
data: Object,
headers?: any,
params?: Object,
success(res: any): any,
fail(err: any): any
}
// 用来json化参数的工具:
// import qs from 'qs';
// get方法:
const axiosGet = (option: option) => {
http.get(
option.url,
{
params: {
...option.data
},
headers: option.headers,
},
).then((res: Object) => option.success(res))
.catch((err: Object) => option.fail(err))
}
// post方法:
const axiosPost = (option: option) => {
http.post(
option.url,
JSON.stringify(
{ ...option.data },
),
{ headers: option.headers, }
).then((res: Object) => option.success(res))
.catch((err: Object) =>
option.fail(err))
}
// 导出基本的请求方法:
export {
axiosGet,
axiosPost,
}
接下来我们再到request.ts中进一步封装:
import { axiosGet, axiosPost } from "./requestMethods";
import axios from 'axios';
// 测试的方法:
const myGetRequest = (url: String, data?: Object, headers?: any) => {
return new Promise((resolve, reject) => {
// 此处的函数内以一个符合request_methods.ts中option接口的对象作为参数
axiosGet({
url: url,
data: data,
headers: headers,
success: function (res: any) {
// console.log('请求结果:', res);
resolve(res);
},
fail: function (err: any) {
reject(err);
}
})
})
}
// post测试方法:
const myPostRequest = (url: String, data?: Object, headers?: any) => {
return new Promise((resolve, reject) => {
// 此处的函数内以一个符合request_methods.ts中option接口的对象作为参数
axiosPost({
url: url,
data: data,
headers: headers,
success: function (res: any) {
resolve(res);
},
fail: function (err: any) {
reject(err);
}
})
})
}
export {
myGetRequest,
myPostRequest
}
上面的请求方法都是返回一个Promise,也符合async await语法对promise的处理。
那么接下来基本就像套公式一样在组件中调用request.ts中的请求方法了,举个栗子:
//部分代码:
//导入对应的请求方法:
import { myPostRequest } from '../../http/request';
......
const sendRegister = async (): Promise<any> => {
// 创建一个临时参数对象:
let templeParams: Object = {
cardId: state.userInput[0].value,
password: state.userInput[1].value,
major: state.depCla[0].value + state.depCla[1].value
}
//请求头:
let headers = {
'Content-Type': 'application/json'
};
try {
// 要传入的为请求路径,请求参数和请求头可选。
const { data: res } = await myPostRequest("/scholarship/user/register", templeParams, headers);
console.log(res);
if (res.code === 200) {
//执行其他回调,success方法我没在这里写。
success();
}
} catch (err: any) {
console.log('error:', err);
}
// 清除临时参数对象:
templeParams = null;
headers = null;
}
上面就使用asyc和await处理请求方法。
uni-app项目:
我们以http目录作为请求拦截、请求方法所在的目录, 
我们在request_methods.ts中封装好请求的方法:
import qs from 'qs';
// 使用typescript中的接口用于规范请求参数option
interface option {
url: any,
data: Object,
method: any,
success(res: any): any,
fail(err: any): any
}
const reqMethod = (option: option) => {
uni.request({
url: option.url,
data: qs.stringify({
...option.data
}),
method: option.method,
success: function (res: any) {
option.success(res);
},
fail: function (err: any) {
option.fail(err);
}
})
}
export { reqMethod }
在request.ts中进一步封装:
import { reqMethod } from "./request_methods";
// 以下为项目中各处需要导出的请求方法,全部使用promise加async aeait方法;
// 测试请求的方法是否可行:
const getNews = (requestUrl: String) => {
return new Promise((resolve, reject) => {
reqMethod({
url: requestUrl,
method: 'GET',
data: {},
success: function (res: any) {
resolve(res);
},
fail: function (err: any) {
reject(err);
}
})
})
}
export { getNews }
使用的方法和vue项目中的差不多,我就不再多说了:
//部分代码:
//记得导入getNews方法;
const myRequest = async (): Promise<any> => {
try {
const {data: res} = await getNews('路径');
console.log(res);
} catch (err: any){
console.log("error:", err);
}
//自行处理语句;
}
内容有点多,就当是记录了。欢迎小伙伴们一起交流学习。
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这