I've got a provider that uses the Http service to perform a GET operation over a localhost server:
requestAchievedCombined(config){
return new Promise( (resolve, reject) => {
const URL = "localhost:3000";
const query = "?collection=achieved_combined&query=columns";
this.http.get(URL+"/api"+query).subscribe( response => {
// TODO: check data integriy
console.log(">> API RES: ", response)
resolve(response);
}, err => this.errorHandler(err, reject));
})
}
The server is hosted in localhost:3000 and running, and it works perfectly when called from the navigator with that same GET query string... it returns some JSON.
Thing is, when I execute my Angular app, this gives me the following error:
ERROR [DataRequester] =>
{…}
_body: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /function%20URL()%20%7B%20%20%20%20[native%20code]%7D/api</pre>\n</body>\n</html>\n"
headers: Object { _headers: Map, _normalizedNames: Map }
ok: false
status: 404
statusText: "Not Found"
type: 2
url: "http://localhost:4200/function%20URL()%20%7B%20%20%20%20[native%20code]%7D/api?collection=achieved_combined&query=columns"
__proto__: Object { constructor: Response(), toString: Response.prototype.toString() }
Do anybody know why this happens? What am I doing wrong? I'm using the latest Angular version.
pd: yes I tried putting http:// before localhost in the URL.
EDIT: After changing the url to http://localhost:3000 and call the property in a proper way (I was forgetting the this. thing), I could manage to communicate with the server, but now I'm having this issue:
ERROR [DataRequester] =>
{…}
_body: error
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: null
defaultPrevented: false
eventPhase: 0
explicitOriginalTarget: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
isTrusted: true
lengthComputable: false
loaded: 0
originalTarget: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
target: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
timeStamp: 3687.8557595446277
total: 0
type: "error"
__proto__: ProgressEventPrototype { lengthComputable: Getter, loaded: Getter, total: Getter, … }
headers: Object { _headers: Map, _normalizedNames: Map }
ok: false
status: 0
statusText: ""
type: 3
url: null
__proto__: Object { constructor: Response(), toString: Response.prototype.toString() }
URL is a global function that gets "called". Try renaming the URL var to url and it should work.
Okay, first thing wrong was that I wasn't calling the URL property in a good way: actually, it wasn't in the method but in the class, and I was forgetting the "this.", so I wasn't pointing to the right variable.
Secondly, fixed my edit simply setting up CORS in my express server:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Now my Angular app correctly gets the data!
I'm just passing by to give you some code
requestAchievedCombined(config): Observable<any> {
const URL = "localhost:3000";
const query = "?collection=achieved_combined&query=columns";
return this.http.get(URL+"/api"+query)
.map( response => {
// TODO: check data integriy
console.log(">> API RES: ", response)
return response;
}, err => this.errorHandler(err))
// .toPromise() // If you still want your cherished promise
;
}
I've changed your function to simplify it : you should use Observables instead of Promises. I know, I was skeptical at first too, but Observables are way more powerful than promises. and if you still don't like it, simply call .toPromise() right after the map operator, it will still be clearer ;)
Other than that, Could you post the trace of your error instead of the payload ? We need the error message to know what is happening.
Related
( https://ikgithub-finder.vercel.app/ )
this is a website im building to search github users following a react course.
im having a problem with the website not catching the response or some axios problem here.
im searching for github user and this is the response, which I didn't had in the building stage.
This is the code repo:
(https://github.com/IdanKfir/github-finder)
and this is what console.log gets from searching a user:
xhr.js:247 GET https://api.github.com/search/users?q=brad 401 asyncToGenerator.js:6 Uncaught (in promise) Ft {message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …} code : "ERR_BAD_REQUEST" config : {transitional: {…}, adapter: Array(2), transformRequest: Array(1), transformResponse: Array(1), timeout: 0, …} message : "Request failed with status code 401" name : "AxiosError" request : XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …} response : {data: {…}, status: 401, statusText: '', headers: n, config: {…}, …} stack : "AxiosError: Request failed with status code 401\n at https://ikgithub-finder.vercel.app/static/js/main.e1a418f5.js:2:193546\n at XMLHttpRequest.d (https://ikgithub-finder.vercel.app/static/js/main.e1a418f5.js:2:193694)" [[Prototype]] : Error
I was trying to change the token I used from git, and the env file was uploaded so I had to delete.
to be honest I thought that was the problem so I reuploaded and again the same error.
Would love sending the whole codes instead of repo but it really lots of code, lucky me if you'll have the time to look for it anyways, thanks :)
I debug your code and find that inside your context/github.js your have a function of searchUser i.e :
export const searchUsers = async (text) => {
const params = new URLSearchParams({
q: text,
});
const response = await github.get(`/search/users?${params}`);
return response.data.items;
};
Here your are direactly getting the value of inside your text parameter so you don't need to user URLSearchParams just direactly pass it to your api call
export const searchUsers = async (text) => {
const response = await github.get(`/search/users?${text}`);
return response.data.items;
};
and if you want to use URLSearchParams you have to pass full url to the function that i see currently you are not doing .
Let me know if this works for you otherwise we will find another way :)
So, soon enough I found an answer to my question :D
To other people who have this problem maybe the solution will be the same;
So it was the token, but the problem was this:
Send Authorization in string
replace
{ headers: { Authorization: Bearer ${userInfo.token} } }
with { headers: { "Authorization": Bearer ${userInfo.token} } }
Trying to refresh the access token I receive from Django every few seconds, however I am getting the error message
Request Method: POST Status Code: 400 Bad Request
I am sending my refresh token to this endpoint: "http://127.0.0.1:8000/api/token/refresh/"
This is my urls.py:
from rest_framework_simplejwt.views import (TokenObtainPairView, TokenRefreshView, TokenVerifyView)
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
urlpatterns = [
path('', include(router.urls)),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
# path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/', CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
path('api/register', RegisterApi.as_view()),
]
This is how I am sending my refresh token:
let updateToken = async ()=> {
try {
let response = await axios.post('http://127.0.0.1:8000/api/token/refresh/',JSON.stringify(authTokens.refresh))
//update state with token
setAuthTokens(authTokens => ({
...response.data
}))
//update user state
const decoded = jwt_decode(response.data.access)
setUser(user => ({
...decoded
}))
//store tokens in localStorage
//we stringify because we can only store strings in localStorage
localStorage.setItem('authTokens',JSON.stringify(response.data))
}
catch(err) {
//if fail, something is wrong with refresh token
console.log(err.response)
}
}
This is the error I am getting:
config: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}
data:
refresh: ['This field is required.']
[[Prototype]]: Object
headers:
content-length: "39"
content-type: "application/json"
[[Prototype]]: Object
request: XMLHttpRequest
onabort: ƒ handleAbort()
onerror: ƒ handleError()
onload: null
onloadend: ƒ onloadend()
onloadstart: null
onprogress: null
onreadystatechange: null
ontimeout: ƒ handleTimeout()
readyState: 4
response: "{\"refresh\":[\"This field is required.\"]}"
responseText: "{\"refresh\":[\"This field is required.\"]}"
responseType: ""
responseURL: "http://127.0.0.1:8000/api/token/refresh/"
responseXML: null
status: 400
statusText: "Bad Request"
timeout: 0
upload: XMLHttpRequestUpload {onloadstart: null, onprogress: null, onabort: null, onerror: null, onload: null, …}
withCredentials: false
[[Prototype]]: XMLHttpRequest
status: 400
statusText: "Bad Request"
[[Prototype]]: Object
This is what i have in authTokens:
{refresh: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90e…9tIn0._aS9oDcj3Rfomodbs9qMEFmgEm4oEdOfSwGSJJKLWmg', access: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90e…20ifQ.K1YCXWoMWF7o61fGAuVm-QoehB3-jA2A_dLZ4o4uYa8'}
The /api/token/refresh/ returns only the access token.
When you setAuthToken using the entire response data, you are most likely getting rid of the refresh token.
Now the next time you make the request, authTokens.refresh is undefined and thus does not get sent to the backend. The backend rightfully complains that it's a 400: Bad Request. refresh is a required field.
Modify your frontend code to only update the access token. When the refresh token expires, you need to call /api/token/ to login again.
Alternatively you can change the backend to rotate refresh tokens. This would send a new refresh token each time the access token is refreshed.
This is achieve by setting ROTATE_REFRESH_TOKENS = True in your settings.
If you want to make sure the old refresh token can no longer be used, you can blacklist them when rotated, by setting BLACKLIST_AFTER_ROTATION = True
I want to use the chrome proxy API. I have this code in my background script but it will not work
const proxyData = []
const fetchProxyData = () => {
axios({
method: "GET",
baseURL: "https://api.getproxylist.com/proxy",
params: {
protocol: "http",
allowsPost: 1,
allowsHttps: 1,
anonimity: "high anonymity"
}
}).then( (response) => {
console.log(response.data)
proxyData.push(response.data)
})
}
fetchProxyData();
var config = {
mode: "fixed_servers",
rules: {
singleProxy: {
host: proxyData.ip,
port: proxyData.port
}
}
}
chrome.proxy.settings.set({
value: config,
scope: "regular"
}, () => {
console.log(`proxy configured with data: ${proxyData}`)
})
I get this error in background page console: background.js:55 Uncaught TypeError: Invalid invocation
I've tried with the example provided with the proxy api documentation and the error will not occur. Maybe it's caused by the config object? To set the proxy as you can see in the code, I'm using an ajax call, maybe is this the problem?
is there any fix?
I have also faced the same problem when I find the solution, it was silly mistake.
I had passed string value to port.
Please make sure you are passing integer value to port
Close. Couple things.
One, you need to fetch your data before calling Chrome's proxy API. And two, your getting the properties for your config from the proxyData array, not the JSON object from your axios call.
You need to do something like this:
const proxyData = [];
const fetchProxyData = () => {
axios({
method: "GET",
baseURL: "https://api.getproxylist.com/proxy",
params: {
protocol: "http",
allowsPost: 1,
allowsHttps: 1,
anonimity: "high anonymity"
}
}).then((response) => {
const {data} = response;
proxyData.push(data);
const config = {
mode: "fixed_servers",
rules: {
singleProxy: {
host: data.ip,
port: data.port
}
}
};
chrome.proxy.settings.set({
value: config,
scope: "regular"
}, () => {
console.log(`proxy configured with data: ${data}`)
});
})
};
fetchProxyData();
What's happening with your code...The properties host and port in singleProxy (in config) are being assigned undefined because those properties don't exist in the array proxyData. They exist in the object returned from your axios call (above, data).
The undefined keys caused Chrome to throw an Invalid Invocation error.
For anyone else getting the Invalid Invocation issue, it seems to me the problem usually lies within the config your passing into Chrome. In particular the types of each key.
In my case, I was passing in the port as a string when it needed to be a number.
I am writing the following pre-request Script to get my JWT for authentication:
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err, res, typeof res);
if(err === null){
console.log(res.header)
// var authHeader = res.header.find(v => {v.key === 'Authorization'})
}
});
This is what the console output currently looks like:
null, {id: "4ba2b741-316e-454d-b896-eab3aef74ae2", status: "OK", code: 200…}, object
undefined
OK
// If you enlarge the opbject it looks like the following:
id: "4ba2b741-316e-454d-b896-eab3aef74ae2"
status: "OK"
code: 200
header: [10] <--- There are my headers ?!
stream: {…}
cookie: [0]
responseTime: 121
responseSize: 0
The problem is I can not access the header array the script always tells me it is undefined, same if I try the access the cookie array. But I can access every other single property, maybe it's because header and cookie are arrays? I don't know. Any ideas what I am doing wrong and how I can get my Authorization header?
I think the Problem must be a bug, my workaround is to stringify and parse the object as json, than the headers are accessible.
r = JSON.parse(JSON.stringify(res))
Problem is I can see the data coming back in the request from browser, but it never reaches where I want it however the http get request fails and outputs the error I put below, I already enabled polyfills that are required, happy to provide if required here.
Error
Browser IE11 has some serious problem with angular7 app i inherited,
HTML1300: Navigation occurred. localhost:4200 DOM7011: The code on this page disabled back and forward caching. For more information, see: http://go.microsoft.com/fwlink/?LinkID=291337 localhost:4200 Angular is running in the development mode. Call enableProdMode() to enable the production mode. TypeError: Object doesn't support this action {
[functions]: ,
__proto__: {
[functions]: ,
__proto__: {
[functions]: ,
__proto__: { },
message: "",
name: "Error",
Symbol(INITIAL_VALUE)_h.02cxvy0t1nq: undefined,
Symbol(rxSubscriber)_g.02cxvy0t1nq: undefined
},
message: "",
name: "TypeError",
Symbol(INITIAL_VALUE)_h.02cxvy0t1nq: undefined,
Symbol(rxSubscriber)_g.02cxvy0t1nq: undefined
},
description: "Object doesn't support this action",
message: "Object doesn't support this action",
name: "TypeError",
number: -2146827843,
stack: "TypeError: Object doesn't support this action at Anonymous function (http://localhost:4200/main.js:7070:17) at TapSubscriber.prototype._next (http://localhost:4200/vendor.js:123833:13) at Subscriber.prototype.next (http://localhost:4200/vendor.js:115824:13) at TapSubscriber.prototype._next (http://localhost:4200/vendor.js:123839:9) at Subscriber.prototype.next (http://localhost:4200/vendor.js:115824:13) at onLoad (http://localhost:4200/vendor.js:13397:21) at ZoneDelegate.prototype.invokeTask (http://localhost:4200/polyfills.js:8075:13) at onInvokeTask (http://localhost:4200/vendor.js:58822:17) at ZoneDelegate.prototype.invokeTask (http://localhost:4200/polyfills.js:8075:13) at Zone.prototype.runTask (http://localhost:4200/polyfills.js:7848:21)",
Symbol(INITIAL_VALUE)_h.02cxvy0t1nq: undefined,
Symbol(rxSubscriber)_g.02cxvy0t1nq: undefined }
Here's the piece of code where it starts having problem,
public myCompanyGet(observe?: 'body', reportProgress?: boolean): Observable<Array<myCompany>>;
public myCompanyGet(observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<Array<myCompany>>>;
public myCompanyGet(observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<Array<myCompany>>>;
public myCompanyGet(observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
let headers = this.defaultHeaders;
// authentication (oauth2) required
if (this.configuration.accessToken) {
let accessToken = typeof this.configuration.accessToken === 'function'
? this.configuration.accessToken()
: this.configuration.accessToken;
headers = headers.set('Authorization', 'Bearer ' + accessToken);
}
// to determine the Accept header
let httpHeaderAccepts: string[] = [
'application/json',
'text/json',
'application/xml',
'text/xml'
];
let httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
if (httpHeaderAcceptSelected != undefined) {
headers = headers.set("Accept", httpHeaderAcceptSelected);
}
// to determine the Content-Type header
let consumes: string[] = [
];
return this.httpClient.get<Array<myCompany>>(`${this.basePath}/api/myController/myMethod`,
{
withCredentials: this.configuration.withCredentials,
headers: headers,
observe: observe,
reportProgress: reportProgress
}
).pipe(
catchError(error => {
console.log(error) // this is where I am getting error
return null
})
);
}