我尝试使用fetch从后端调用使用react,而不使用libs(例如Axios)。所以我创建了这个函数:
export function api(url, method, body, isHeaderContentType,isRequestHeaderAuthentication,header, succesHandler, errorHandler) {
const prefix = 'link';
console.log("url:",prefix+url);
const contentType = isHeaderContentType ? {
'Content-Type': 'application/json',
} : {};
const auth = isRequestHeaderAuthentication
? {
Authorization: `Bearer ${AuthUtils.getTokenUser}`,
}
: {};
fetch(prefix + url, {
method,
headers: {
...contentType,
...auth,
...header,
},
protocol:'http:',
body,
})
.then(response => {
response.json().then(json => {
if (response.ok) {
console.log("method", json);
if (succesHandler) {
succesHandler(json)
}
} else {
return Promise.reject(json)
}
})
})
.catch(err => {
console.log("error",`${url} ${err}`);
if (errorHandler) {
errorHandler(err);
}
})
} 并称之为
api(
`link`,
"GET",
null,
true,
true,
null,
response => {
this.setState({profile:response.data})
},
err => {
console.log('error', err);
}
);
我在这个函数中调用我的api():
getProfileUser = () =>{
if (!isUserAuthenticated()){
history.push('/signin')
}else {
api(
`link`,
"GET",
null,
true,
true,
null,
response => {
this.setState({profile:response.data})
},
err => {
console.log('error', err);
}
);
}
};
这是我的全部内容:
export default class Profile extends Component {
constructor(props) {
super(props);
this.state = {
profile:[]
}
}
getProfileUser = () =>{
if (!isUserAuthenticated()){
someCode
}else {
api(
`link`,
"GET",
null,
true,
true,
null,
response => {
this.setState({profile:response.data})
},
err => {
console.log('error', err);
}
);
}
};
componentDidMount() {
this.getProfileUser();
}
render(){
return(
<div>
hello
</div>
)
}
}
但是当我试图运行它时,我得到了一个像这样的错误
TypeError:无法执行&#39; fetch&#39; on&#39; Window&#39;:无效值
有没有人知道我的代码有什么问题?当我使用&#34; POST&#34;方法,但是当我使用&#34; GET&#34;时它不起作用。方法
答案 0 :(得分:6)
对我来说,标题对象的键中有一个无效字符。我不小心包含了“:”,这引发了描述的错误。在chrome控制台中很难真正看到。希望对别人有帮助。
{ 'Authorization:':'Bearer etc...' }
答案 1 :(得分:5)
当我尝试在我的fetch调用中添加Authorization
标头时,这也发生在我身上。在我的情况下,它是由标题字符串中的换行符引起的,即Bearer:\nsomelong-token
。更改为新线到空间解决了问题。
答案 2 :(得分:3)
我将带有换行符的字符串传递给标题对象,例如:
const myString = 'this is a string \nand this is a new line';
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
'subscriptionId': myString
}
答案 3 :(得分:1)
我遇到了同样的问题,但是使用Angular 7时,我正在使用这样的Interceptor服务:
// headerservice.ts
public intercept() {
const token = Cookies.get('token');
this.Language = Cookies.get('language');
this.headers = new HttpHeaders(
{
Authorization: 'JWT ' + token,
'Accept-Language': this.Language
}
);
return this.headers;
}
//other file
this.headers = this.headersService.intercept();
但是在我正在执行获取操作的其他文件上它不起作用,因此我删除了服务并将标头直接放在函数内,它可以工作! 像这样:
const token = Cookies.get('token');
const language = Cookies.get('language');
const headers = {
Authorization: 'JWT ' + token,
'Accept-Language': language
}
const fetchParams = { method: 'GET',
headers: (headers) };
fetch(url, fetchParams)
答案 4 :(得分:1)
嘿,我在尝试使用 react 中的 fetch 方法加载数据时遇到了同样的问题。
const response = await fetch('/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query
})
});
我在 Content-Type 中有一个导致错误的额外空间,因此请查找相同的空间。
答案 5 :(得分:0)
这个错误也发生在我身上,但是情况有所不同。如果有人遇到此问题,我想分享一下。
当我尝试使用HTTP POST上载文件而不使用FormData时,出现错误“ TypeError:无法在'Window'上执行'fetch':无效值”。为了解决该问题,我使用了FormData对象,并附加了属性和文件本身:
$(function()
{
var $section = $('.progress-element');
$(document).bind('scroll', function(ev)
{
var scrollOffset = $(document).scrollTop();
var containerOffset = $section.offset().top - window.innerHeight;
if (scrollOffset > containerOffset)
{
$(document).unbind('scroll');
$(".progress-element").each(function()
{
var progressBar = $(".progress-bar");
progressBar.each(function(indx)
{
$(this).animate({"width": $(this).attr("aria-valuenow") + "%"}, 500);
});
});
}
});
});
然后我使用fetch通过POST方法发送文件。这是伪代码:
let formData = new FormData();
formData.append('name', fileName);
formData.append('data', file);
答案 6 :(得分:0)
我已经通过将前端url添加到后端代码的白名单cors中来解决此问题
答案 7 :(得分:0)
在我看来,这是因为我写的是“内容类型”而不是“内容类型”
答案 8 :(得分:0)
对我来说,发生错误是因为调用fetch()时,我在GET请求中包含了“ body”。排除GET请求的正文可以解决问题(例如,如果您要编写处理不同HTTP请求类型的通用函数或框架)。这是一个简单的代码摘录,以说明该解决方案(显然,该代码需要在现实世界中进行扩展,但这很重要):
// Earlier code that specifies the HTTP method
let method = 'GET';
// Create fetch() init object
let fetchInit = {};
if (method !== 'GET') {
fetchInit.body = yourRequestBody;
}
// Start network request
fetch(url, fetchInit).then...
答案 9 :(得分:0)
当我像这样对标题进行字符串化时出现此错误:
fetch(http://example.com,
{
credentials: "include",
headers: JSON.stringify({
foo: localStorage.getItem("foo"),
}),
})
我通过删除 JSON.stringify 来修复它:
fetch(http://example.com,
{
credentials: "include",
headers: {
foo: localStorage.getItem("foo"),
},
})
答案 10 :(得分:0)
我遇到过类似的问题- “无证 类型错误:无法在 'Window' 上执行 'fetch':值不是有效的 ByteString。"
在使用 Swagger 进行测试时。在我检查了介于两者之间的令牌后,它得到了解决。请务必从 Web 浏览器复制令牌,如果字符串很长,它们往往会放置 elipsis(...)。
答案 11 :(得分:-1)
对我来说,解决方案是不通过 GET 方法发送正文。
async request(url, method, data) {
const options = {
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
method: method,
credentials: "include"
};
if (['POST', 'PUT', 'DELETE'].includes(method)) {
options.body = JSON.stringify(data);
}
return await fetch(url, options);
}